Java. Part I

 

内容摘要这是一系列有关 Java 程式设计的第一篇文章。 首先, 文中将介绍到, 以程式语言的角度来看, Java 有哪些一般性的特徵, 并提供相关资讯的出处所在。




简介

本文是一系列文章中的第一篇, 将用来介绍 Java 程式设计语言, 与其开发环境。 首先, 我会尝试避免讨论有关此一程式语言的历史、 微波、 或是洗衣机的相关议题 ( 如果有人真的对这些东西感兴趣, 那麽可以从很多出版品中, 得到这些资讯, 甚至在典型的文学作品中, 也可以找到 )。 我也会跟 Duke 划清界线 ( Java 的吉祥物 ), 他是一个有著巨大鼻子和三角形身体的家伙, 它的手会随著马林巴琴 (marimba) 的节奏摇摆, 这让我想起了老式的美国科幻片。

在这股 Java 狂潮中, 似乎带动起一些流行, 市面上每一本电脑杂志, 只要能沾上边, 都会报导它, 也有许多软体公司, 争相地发表可以发展 Java applets 的产品, 甚至几乎每个网站都会放上几个 Java applet。

透过这一系列的文章, 我将尽可能地, 带领大家深入研究, 并且完整学习这个程式语言。 对基本的东西来说, Java 倒是容易就做到了, 但在同时间内, 要精通它是很复杂, 而且很困难的, 因为 Java 目前还不断在演进。

在系列文章的前几篇里, 我们的目标, 在於提供对程式语言的一般性介绍, 将来我们才能学习更深入的主题, 像是 applets、 与网路有关的研究、 JDBC、 Java bean 等。

我必须强调的是, Java 属於一般性用途的程式语言, 虽然它最常被用来撰写 applets, 但它绝不限於网页撰写的功能上。 我们不能将 Java 局限於此, 因为还有许多其他用途, 可能都比撰写 applets 来得更有趣。

在这个第一篇文章里, 我们著重「描述性」多过於「实用性」。 在接下来的文章中, 我们将会深入探索程式语言的基本特徵, 还有程式语言的发展环境。 只有在最後的时候, 我们才会看到一个 java 程式的范例。

起源

Java 是在一九九一年时, 於 Sun 公司 (Sun Microsystem Inc.) 中, 由 James Gosling, Patrick Naughton, Chis Warth, Ed Frank 以及 Mike Sherindan 这些人所构想出来, 初期花了十八个月的时间来发展原型。 从一九九二年到一九九五年之间, Bill Joy, Arthur Van Hoff, Jonathan Payne, Frank Yellia, Tim Lindolm 加入, 合力改善这个初始原型的成熟度.

从这个时间可以清楚地看出, Java 的出现比 WWW 的出现更早, 至少可以说是同时, 因为 Tim Berners Lee 到一九九一年之前, 尚未发展出 HTML 语言。

Java 的语法上, 和 C 语言非常相似, 其物件导向的特性, 也与 C++ 相仿, 但 Java 是一个体系连贯完整, 而且逻辑性一致的程式语言。

Java 本身和 C 与 C++ 的相似程式, 让人很容易联想为 Internet 版的 C++ 语言, 不过, 它们在理论与实作上, 还是有许多重大的差异。 和 C ++ 相较, Java 特别改善与精简了物件导向的基本架构。

Internet 让 Java 声名大噪, 使得它成为一种广为人知的程式语言, 值此同时, Java 也对 Internet 有著极为深远的影响, 因为它让网路世界的物件, 能够自由移动的空间范围, 加大了许多 ( 指的是「能够自我执行的动态程式」 )。

JAVA 之取得及安装方法

有许多工具, 对 Java 程式设计来说, 都是非常重要的。 附带地, 我所提到的状况, 都是指在 GNU/Linux 的环境下 ( 怕有人会搞混了 ):

目前 ELF 版本的程式, 需要使用到 1.2.13 版本或之後的核心程式。

我将会使用 JDK (Java Developement Kit) 工作环境, 2.0.14 版本或之後的 Netscape, 以及一个类似 Xemacs 的文字编辑器。 我们打算在 Xwindows 环境下进行, 虽然未必一定都要如此, 但发展 Applet 与应用图形介面的程式时, 就必须使用到它。

JDK 相关程式, 可由下列的网址下载取得:

http://www.blackdown.org/java-linux.html

从这个网址, 您可以选择出一个较方便的映射站台, 以快速下载这些档案。 几个月前, 最新的版本是 JDK-1.1.3 ( 这也是本文所使用的版本 ), 不过, 我上次已在站上看到 1.19 版出来了。 值得注意的是, 假如我们下载了所有的程式, 大概会有 24 Mb! 就算是只下载最精简的部份, 也要大概 12 Mb 的容量 ( 所以耐心点吧! )。

以 gunzip 解开压缩档之後, 应该不会遇到什麽障碍, 接下来就可以工作了。

通常我们会将程式都安装在 /usr/local 目录下, 然後建立一个 /JDK1.1.3 子目录, 而里面会有下列的内容:

/doc 以 HTML 格式写成的正式文件

/demo Java 示范程式

/lib 函式库

/bin 放的是 JDK 主要的工具程式

在 /lib 目录里, 我们可以找到 "classes.zip" 档案 ( 不要把这个档解开 ), 它包含了所有已编译好的类别档案, JDK 会用到它们。

在根目录里, 我们可以找到 "src.zip" 档案, 当中包含了 classes.zip 里的原始档案, 不过它们不能被拿来编译, 它们只做为提供程式的参考之用。

发展环境

如同前面所提到的, 发展 JAVA 程式所会用到的工具程式, 都放在 /bin 目录之下:

javac : Java 的编译器, 可以把 Java 语言写的原始档编译成 bytecode 的形式。

Java : Java 解译器, 可以执行 bytecode 形式的 Java 程式码。

jre : 另一种跟 Java 相似的解译器, 不同点在於, jre 可以跟著您写好的程式一起散布给每个人, 那些不需要所有功能的使用者, 就能方便地执行。

appletviewer : 用来测试与执行 applets。

jdb : 除错器。

javap : Java 反组译器, 可以将 Java 编译而成的 bytecode, 还原成原来文字档形式的程式码。

javadoc : 文件产生器, 可以产生许多 HTML 形式的文件, 用以描述公开类别 (public classes) 或是私有类别 (protected classes)、 界面 (interfaces)、 建构子 (constructors)、 方法 (methods)、 栏位 (fields)。 这个工具也可以产生类别之间的阶层架构, 以及其所有成员的索引。

javah : 可以将原生方法 ( 由 C 语言所撰写成 ) 加入 Java 程式中的工具程式。

jar : 用来将 java 之类别与原始码程式, 压缩为 Jar 档案的程式。?

javakey : 用来维护数位签章的工具程式。

updateAWT : 应用程式里, 使用了 AWT1.02 的方法, 要使用此程式来更新那些已改变的名称。

To work without glitches with the current directory structure I advise you to add /usr/local/JDK1.1.3/bin to the environment variable PATH. If you wish to make the development environment available system wide then fix the PATH variable in the /etc/profile file.

特徵

让我们先暂停一下, 向自己问个问题: 什麽是 Java ? 依照 JDK 使用说明所述, 我们可以这样回答: Java 包含两种意义, 它一方面是一种程式语言, 另一方面也是一种平台环境。

以程式语言的角度来看, Java 是一种高阶语言, 具有下列特色 ( 某些程度上, 我们会解说其细节 ) :

  • 简单
  • 物件导向式
  • 分散式
  • 直译式
  • 强固
  • 安全
  • 与系统架构保持中立
  • 可携性高
  • 多执行绪
  • 动态式
  • 高解析

首先吸引我们注意力的是, Java 以直译方式运作, 虽然说 Java 原始码必须预先经过编译过程, 以产生 bytecode 型式之物件, 但此物件已是低阶的程式码了, 可以在多种平台上被直译执行了。

由於 Java 的 bytecode, 我们可以做到「编写一次, 到处执行」的境界。 我们可以将 Java 程式於某一平台上编译, 并在另一个完全不同架构的平台上执行, 只要该平台上具有 Java Virtual Machine (JVM) 功能。 举例来说, Java 程式可以在 Windows NT 平台上编译, 然後在 Sun Ultra Solaris 上执行无误 ( 至少理论上是如此 )。

一般而言, 所谓「平台」指的是, 某种应用程式可以在上面执行的软硬体环境。 然而, 对 Java 而言, 平台只是程式执行的软体环境, 每个 Java 平台必须执行於某个硬体平台之上。

Java 平台具有下列两项内容:

  • Java Virtual Machine (JVM)
  • Application Programming Interface (API)

JVM 是一种抽象化的电脑, 我们可以在上头执行 Java 预先编译过的程式。 它本身的设计原则是「小而简单」, 因为其目的, 是为了尽可能在所有机器上都能安装。 这样的精简原则, 使得它机会能够在现有的平台上都可以顺利执行, 有助於提供给所有人一个共通的软体介面, 针对异质网路的环境 (诸如 Internet), 它可以解决不少可携性的问题。 由此可知, 这项科技之所以能够不断推陈出新, 其主要原因应该在此。 仅管「虚拟机器」的概念, 不该只被视为是软体介面, 但如其名称所示, 目前它已逐步迈向完整之电脑系统, 没过多久, 我们可以看到市面上会有 Java 晶片出现, 用来支援真正的 Java 机器、 信用卡、 电视解码器等。

Java 之 API 是一个大型的软体元件集合, 其提供许多种工具, 诸如使用者图形介面 (GUI) 即为一例。 它们是以函式库方式组成 ( 依 Java 之说法, 即为 Java 包裹 ), 藉由这些函式库, 可以来产生许多种 Java 的应用程式, 而不限於众所皆知的网页 Applet, 举例来说, 诸如网页伺服机、 快取代理伺服机、 邮件伺服机、 IRC 伺服机、 甚至所有我们可以想像得到, 与 Internet 有关的东西。

我们可以将「API 包裹」分类成下列几种:

  • 基本类: objects, matrixes, numbers, input and output, data structures, properties of the system, date, time, etc.
  • Applets : set of functions and utilities used to craft Java applets.
  • 网路类: URLs, TCP, UDP, sockets, IP addressing.
  • 与多国语文支援相关: Helps to write code that can be easily adapted to local specifications and can be visualized in a native language.
  • 与系统安全相关: low and high level, including digital signature, public and private keys, access control and certificates.
  • 与软体元件相关: known as JavaBeans.
  • 与资料库相关: provides uniform access to a large number of relational databases.

除了这些基本的 API 核心外, 另外还有诸如 3D 延伸功能, 行动通讯 (mobile communications), 动画等。

在本章节的开头, 我们已经提过 Java 有一系列的特色, 以下我们将更详细地介绍它们:

简单: 在 Java 里面, 我们总可以由几个定义好的格式, 来完成某一项工作。 一般功能强大的程式语言, 其所有的功能都能由 Java 来提供, 但 Java 却把那些不常使用, 或是容易造成混淆的功能, 都给拿掉了。 Java 继承了 C/C++ 的语法, 以及许多 C++ 物件导向的特色, 任何一位熟悉 C/C++ 的程式设计师, 都能轻松地学习 Java。 仅管它们之间有这些相似处, Java 还是去除了一些 C/C++ 的特色, 包括有:
  • 指标运算
  • Registers (struct)
  • 型态定义 (typedef)
  • 巨集 (#define)
  • 需要释放记忆体 (free)
  • 没有多重继承
  • 没有运算元的重载
  • 在 unions 里没有 structures
物件导向式: Java 由完全没有的情况下开始设计, 因此对於物件导向, 它所使用的的方式非常的清楚实用。 Java 的物件模型十分简单, 而且容易使用。
分散式: Java 在设计上, 可以很容易 TCP/IP 进行沟通, 事实上, Java 允许程式发展者在存取网路上的资料时, 就好像存取自己电脑上的档案一样简单。
强固: Java 是一种非常注重形态转换的语言, 所以在编译时期 (compile-time) 就会做形态转换检查, 在执行时期 (run-time), Java 也会做一些形态上的检查。 由於 Java 直译器实作了自动垃圾搜集器 (automatic garbage collector), 在这里垃圾指的是一些不会再被使用的物件, 所以不必程式设计者费心, 记忆体也会被自动地管理。 Java 本身提供了许多物件导向的例外处理常式, 所以一个撰写良好的应用程式, 在执行时期所发生的错误, 都可以由程式自己来处理.
与机器架构无关: Java 的设计者设计 Java 的主要目的, 就是希望程式可以做到, 「只写一次, 就可以随时随地在任何地方执行」。 Java 写成的程式码, 会被编译成高阶的 byte code, 它们与机器架构无关, 这种 byte code 被设计用来在任何执行环境 ( Java 直译器 ) 上执行, 然而这些执行环境是与机器相关的。
安全: 当需要分散式资讯时, 需要客户端作业系统有很高阶的安全机制, 由於 Java 在其执行时期环境的一些特色, 使得 Java 提供了安全机制:
  • bytecode 验证器
  • 执行时期系统记忆体的取得方式
  • 档案存取限制

即使经过编译器产生了正确的 byte code, 解译器在执行这些 byte code 时, 会再做一次双重确认, 以确保这些 byte code 自从编译过後, 没有被更改过 ( 不管是不是故意的 )。 Java 直译器更进一步决定各个类别所能取得的记忆体, Java 被认为是在任何系统上最安全的应用程式之一。

可携性: 撇开 Java 基本的可携性来说, 为了达到真正与机器架构无关, Java 实作了可携性标准: 整数永远是整数, GUI 包括了抽象的视窗系统 (AWT), 因此它是与机器架构 (UNIX, PC, MAC) 无关的。
It is interpreted: To achieve one of the basic goals of Java, platform independence, the java compiler generates an intermediate code (bytecode). It can be executed on any system with the proper interpreter. This paradigm may let us wonder on the possible performance problems of java applications. Nevertheless, and because of this performance concern, Java creators have tried to keep the bytecode design as simple and as easy to translate into machine code as possible in order to keep the highest performance possible.
It is multithreaded: It is simple to write Java applications that can execute several tasks at the same time in a robust way.
It is dynamic: Java does not try to link all the modules that form an application until run-time. This feature helps to link the code dynamically safely and conveniently.

After this long "speech" (much of which can be found in the official Java documentation) one can wonder about the status of Java in the GNU/Linux world. We mentioned earlier the availability of JDK for Linux, which is nothing but a commercial implementation developed by Sun Microsystems (although freely distributable).

There are tools like the compiler GUAVAC under GPL license, that let us compile any Java source without problems. We should also mention a virtual machine called KAFFE under Berkeley license. The last two projects are in a very advanced stage although still need of the Java class libraries from Sun (of free distribution at the moment) in order to have a complete development system.

Several recent projects, still in an early stage, aim at providing development environments to fast and visual applications.

Finally I would like to state that there is a great movement on the net concerning Java and GNU technologies, especially concerning the development of the complete tool box of free-distribution for Java and independent from Sun. We can already understand the importance of Java, and when the fashion is over I am sure that something is going to remain of it (I venture to say a lot of it is here to stay).

第一个用 JAVA 写的程式

After seeing some of the general characteristics of the language let us take a look at a real program. As I mentioned in the introduction, I would like as much as possible to stay away from typical stuff, like the hello world example, instead let us start with a program that draws a square of any dimension we like (a bit complicated but not too much):

File Cuadro.Java

class Cuadro {
public static void main (String args[]) {
        int l ,a;
        if (args.length == 2) {
            l = Integer.valueOf(args[0]).intValue();
            a = Integer.valueOf(args[1]).intValue();
         }
         else {
          l= 20;
          a= 15;
         }
          for (int i=l; i>0; i--){
            System.out.print("*");
            }
            System.out.print("\n");
            for (int i= a-2; i>0; i--){
             System.out.print("*");
               for(int j=l-2; j>0; j--) {
                  System.out.print(" ");
                  }
                  System.out.print("*\n");
                  }
                for (int i=l; i>0; i--){
                System.out.print("*");
                }
              System.out.print("\n");
           }
}

In Java the name given to the source file is very important because it defines a "compilation unit". The file may contain one or more definitions of classes. The compiler expects the source file to have the extension .Java (4 characters) consequently some systems do not support it (DOS or Windows 3.1)

In the example given the name of the class defined coincides with the name of the source file. This is not by chance, in Java all code must be in a class. By convention the name of the class has to coincide with the name of the source file containing the class.. Moreover Java is case sensitive (upper or lower case).

To compile the example from the command line type:

> javac Cuadro.java

The Java compiler (if everything went OK) will generate the file Cuadro.class that naturally contains the binary (bytecode) form and it can be immediately executed by the interpreter as:

> java Cuadro

When java source code is compiled, each class in individually placed in an archive with the same name as the class. It is then a good habit to give the source files the same name as the class contained in them so that the source filename will coincide with the archive.class file.

Despite the simplicity of our example Cuadro.java it helps us understand the fundamentals of Java and in particular the structure of a typical java program.

First take into account that this example is not an applet that can be included in a HTML file but an independent program to be executed by the java interpreter on the command line.

The first line of the program is:

class Cuadro {

The first word is a reserved token of the language, it indicates the definition of a new class named in this case "Cuadro" -- Square in spanish -- The exact definition of the class including all its members follow in between two curly brackets {}. Note that in Java all the activity of a program resides inside a class.

In the following line:

public static void main (String args[]) {

it declares a method named main(). All Java applications start their execution with a method called main() (similar to C/C++). Next let me comment a few details necessary to understand the example (in later articles we will explained them in more depth).

The keyword public control the scope of the member methods of the class. When a class is declared public, then the class can be used by code defined outside the class. The keyword static forces the main() method to be invoked without needing to instigate the class. Void indicates that this method does not return any value. To pass parameters to a function or method one uses the parenthesis written after the name of the function, in our example main takes as parameter a matrix of instances from the class String.

Obviously all the code belonging to the method is also enclosed between curly brackets. Next, in the line:

 int l, a ;

we declare two integer variables. In Java every variable must be declared before it can be used. Notice each instruction in the code ends with a semi-colon ";".

The remains of the code implement a small algorithm that :

  1. Test whether the right number of arguments have been provided
    If (args.length==2)
    
  2. If parameters are provided, then they are assigned to the integer variables:
      l = Integer.valueOf(args[0]).intValue();
      a = Integer.valueOf(args[1]).intValue();
    
  3. Otherwise the variables are initialized to default values:
      l = 20;
      a = 15;
    
  4. The rest of the program is nothing more than the instructions needed to draw a square on the screen. We can point specially to:
    System.out.print()
    

    where print() prints the string passed as argument. System is a predefined class that gives access to the system and out is the output stream connected to the console. Also,

    for (int i=l; i>0; i--)
    

    As expected it behaves as our experience with C/C++ and other languages tells.

A nice piece of homework the reader can do using this little code is to test how to compile it and execute it, but also to test the portability of the code by running the compiled object Cuadro.class under various platforms: Linux, windows 95 (but don't take this as a present!) and see that it runs the same on any platform.

总结

我们已经由程式语言的角度, 分析了一些 Java 的特色, 至此, 我们才准备好开始可以写程式, 往後还有很长的一段路要走, 接下来的文件中, 将提供更深入的说明。 预告下一篇的内容, 我们将研究变数的定义方式与其类型, 基本指令, 以及类别等, 这些都是 Java 最主要的独特点。

每篇文件当中, 我都会附上参考资料、 出版书籍、 网路资源等, 这些是我撰写此一系列文件的基础。

  • JAVA Reference Manual. Patrick Naughton Herbert Schildt. McGraw-Hill.
  • Programming with JAVA. Tim Ritchey. Prentice Hall.
  • Tutorial de Java . Spanish manual in HTML format that can be obtained at www.fie.us.es/info/internet/JAVA. Agustín Froufe.
  • The Java Tutorial. English manual in HTML www.javasoft.com. Sun.
  • Tutorial from the JDK distribution.

本文由 Penelope Marr 所翻译