现在,您对 Java 代码的大概样子以及应该如何在您的测试机器上编译并运行 Java 程序有了一个基本的概念,已经准备好开始深入了解 Java 语言的结构和语法了,包括 Java 编程环境和 Java 中标准的数据类型。由于您已经对 Visual Basic 中的编程非常熟悉,因此我们将通过对 Java 和 Visual Basic 进行比较来学习 Java 编程的知识。我们将通过对 Java 平台上的基本组件与 Visual Basic 编程框架中相应组件的对应关系及其区别对 Java 平台上的基本组件进行介绍。如果您是一个 C/C++ 程序员,就可以跳过本节,转而参考免费的 developerWorks中的“ Java programming for C/C++ developers”指南。
Visual Basic 执行环境
Visual Basic 是一种高级编程语言;其目的是简化人类开发计算机程序的过程。计算机并不能理解高级语言;它们只能理解低级的机器语言——即可以直接在计算机的处理器上执行的二进制指令序列。出于这个原因,使用高级语言编写的程序在计算机上运行之前必须被转换成机器语言的程序——即可执行程序。不同的计算机使用的机器语言也不同。在一台计算机上可以运行的可执行程序在其他使用不同机器语言的机器上可能无法运行。
将高级编程语言的可执行程序转换成机器语言的可执行程序有两种方法:编译和解释。编译是将使用高级语言编写的程序全部转换成一个完整的机器语言程序,后者就完全可以执行了。解释是将一个高级程序逐行转换成机器指令;每一行指令都是在下一行指令之前被翻译并执行的。编译和解释在逻辑上是等价的,但是编译后的程序的执行速度比解释后的程序速度更快。Visual Basic 程序使用一个称为编译器的程序编译成机器语言可执行程序。
Java 执行环境
与 Visual Basic 程序一样,Java 程序也会被编译。但是 Java 程序有一点与 Visual Basic 程序不同:Java 程序并不会被编译成与平台相关的机器语言。相反,Java 程序被编译成一种与平台无关的语言,称为 字节码。虽然字节码与机器语言非常类似,但是字节码并不是被设计用来在真正的物理机器上运行的。相反,它被设计用来通过一个名为 Java 虚拟机(JVM)的程序运行,JVM 模拟了一台真正的机器。
简单来说,JVM 是一个解释器,负责将 Java 字节码转换成真正的机器语言指令,后者可以在底层的物理机器上执行。更具体一点说,术语 Java 虚拟机通常就用来表示执行 Java 类文件的任何程序。Java 解释器程序 java.exe 就是 JVM 的一个特定实现。
Java 平台使用虚拟机器层来确保使用 Java 语言编写的程序是与平台无关的。Java 程序一旦被编译成字节码之后,就可以在具有 JVM 的任何系统上运行。这些系统包括 UNIX、Linux、Windows 以及其他很多系统。使用其他语言编写的程序必须对每一种要在其上执行的平台都重新进行编译,而 Java 程序只需要编译一次即可。
数据类型
Java 语言有两种不同类型的数据:类定义(或将其作为 SDK 或第三方类库的一部分使用)和“原始的”(primitive)类型( boolean , char , byte , short , int , long , float 和 double ),Java 运行库可以直接理解后者。大部分 Java 原始类型在 Visual Basic 中都有等价的类型,用户定义的类与 Visual Basic 中的类大部分都非常相似。表 1 列出了 Java 语言中的原始数据类型及其在 Visual Basic 中等价的类型。
表 1. Java 语言的原始数据类型及其在 Visual Basic 中对应的数据类型Java 原始类型 范围 Visual Basic 类型 说明 boolean
true, false Boolean
booleans 类型的合法值只有 true
和 false
。char
0 - 65535 String
(长度为 1)Java 语言使用 Unicode 对字符进行编码。 byte
8位整数(有符号) Byte
? short
16位整数(有符号) Integer
? int
32位整数(有符号) Long
? long
64位整数(有符号) N/A ? float
32位浮点数 Single
? double
64位浮点数 Double
? N/A ? Variant
Java 语言没有 Variant
类型。N/A ? Date
Java 语言没有对应的原始数据类型。您可以使用 Date
类。N/A ? Currency
Java 语言没有对应的原始数据类型。您可以使用 BigDecimal
类。
清单 2 给出了在两种语言中声明原始数据类型的一些例子。
清单 2. 声明原始数据类型
2 Option Explicit // Note that all Java
3 Dim LetterJ As String, I As Integer, x As Byte // variables must be declared
4 Dim Point1 As Single, Point2 As Double // before they can be used
5 Dim IsEmpty As Boolean char letterJ = 'j';
6 LetterJ = "j" int i = 0;
7 I = 0 byte x = 12
8 X = 12 boolean isEmpty = false;
9 IsEmpty = False float point1 = 1.1F;
10 Point1 = 1.1 double point2 = 0.0025;
11 Point2 = 0.0025
12
操作符
在 Visual Basic 和 Java 语言中,操作符具有很多共同点,也有很多关键的区别。Java 语言使用的操作符集与 C 和 C++ 使用的操作符集完全相同。表 2 类出了在这两种语言中最常使用的一些操作符。
表 2. Visual Basic 和 Java 语言中的操作符Java 操作符 说明 用法 Visual basic 操作符 说明 ++
自增 ++num
num++ N/A 这个一元操作符允许对一个非浮点数字执行自增运算。 --
自减 --num
num-- N/A 这个一元操作符允许对一个非浮点数字执行自减运算。 *
/
乘
除num * num
num / num
*
/
? /
整除 num/num
\
Java 语言对于整除和数学除使用同样的操作符。如果操作符是整数,那么就执行整除运算。 %
取模 num % num
Mod
? +
-
加
减num + num
num - num
+
-
? +
字符串拼接 str + str
&
? <
<=
Less小于 than
Less 小于或等于than or equalexpr < expr
expr <= expr
<
<=
? >
>=
大于
大于或等于expr > expr
expr >= expr
>
>=
? !=
不等于 expr != expr
<>
? ==
等于(基本类型) expr == expr
=
? ==
等于(对象) obj == obj
Is
? !
逻辑非 !boolean
Not
Visual Basic 对整数执行的位反和对布尔表达式所执行的逻辑非运算使用相同的操作符,而 Java 则不是。 ~
位非 ~int
Not
? &
位 AND
布尔 ANDint & int
expr & expr
And
? |
位 OR
布尔 ORint | int
expr | expr
Or
? ^
位 XOR
布尔 XORint ^ int
expr ^ expr
Xor
? &&
条件 AND if (expr &&expr)...
And
Java 语言对条件与和逻辑布尔与使用不同的操作符。 ||
条件 OR if (expr || expr) ...
Or
Java 语言对条件或和逻辑布尔或使用不同的操作符。 N/A 模式匹配 str Like pattern
Like
您可以使用 Java 中 String 对象的方法来实现 Visual Basic 中这个操作符的功能。
Visual Basic 的函数和子过程与 Java 方法的比较
在 Visual Basic 中您可以定义函数和子过程。函数与子过程之间的主要区别是子过程没有返回值,而函数有返回值。在 Java 术语中,函数被称为 方法 。Java 语言中没有与 Visual Basic 中的子过程等价的概念。然而,在 Java 语言中,您可以使用关键字 void 定义一个没有返回值的方法,这基本上就等价于一个子过程。您可以将 Java 方法声明为类的成员;但是不能在一个 Java 类之外定义方法。清单 3 给出了一个具有返回值的 Java 方法和一个没有返回值的 Java 方法。
清单 3. Java 方法的返回类型
2
3 // This method doesn't return a value
4
5 public void myMethod1(String arg) {
6
7 ...
8
9 }
10
11 // This method returns an integer
12
13 public int myMethod2(String arg) {
14
15 int i;
16
17 ...
18
19 return i ;
20
21 }
22
23
数组
在 Java 语言中,数组是具有很多属性的对象,其中最重要的是 length 属性,您可以使用这个属性来确定数组的大小。Java 数组通常是从 0 开始索引的,并且数组声明的大小中就包含了第 0 个元素。因此,大小为 100 的数组就意味着其有效的索引值是从 0 到 99。还有,方括号([ ])标记用来说明数组的类型,而不是数组名。Java 语言允许您将数组初始化为预设的一组值。清单 4 给出了一些例子。
清单 4. 数组
2 'An array with 100 integers // An array of 100 integers
3 Dim a(99) As Integer int[] a = new int[100];
4
5 'An array of Strings initialized // An array of Strings initialized
6 b = Array("Tom","Dick", "Harry") String[] b = {"Tom","Dick", "Harry"};
7
8 'Iterating through an array // Iterating through an array of length 100
9 ' of length 100 int [] c = new int [100];
10 Dim c(99) As Integer for (int i = 0; i <.length; i++) {
11 For i=0 To UBound(c) c[i] = i;
12 c(i) = i }
13 Next
14
15
字符串
Visual Basic 有一个 String 数据类型来表示字符串。您可以使用 String 类来表示 Java 中的字符串。Visual Basic 和 Java 中的字符串都可以表示成使用引号括起来的一系列字符。在 Java 语言中,您有两种方法可以创建一个 String 对象:您可以使用一个字符串声明,也可以使用一个 构造函数。 String 对象是不可变的,这就是说一旦您为一个 String 对象赋了一个初值,就不能再修改它了。换而言之,如果您希望修改一个 String 引用对象的值,就必须为这个引用分配一个新的 String 对象。由于 Java 中的字符串就是对象,因此您必须使用 String 类中定义的 接口才能与其进行交互。(在本文后面 面向对象编程简介 一节中您将学习到更多有关构造函数和接口的知识。) String 类具有非常丰富的接口,其中提供了一些非常有用的方法。
清单 5 向我们展示了一些最常用的方法。请尝试编译并运行这个例子。记住将源文件命名为 StringTest.java,不要忘记文件名的大小写是非常重要的。
清单 5. Java 语言中的字符串
2
3 * The StringTest class simply demonstrates
4
5 * how Java Strings are created and how
6
7 * String methods can be used to create
8
9 * new String objects. Notice that when you
10
11 * call a String method like toUpperCase()
12
13 * the original String is not modified. To
14
15 * actually change the value of the original
16
17 * String, you have to assign the new
18
19 * String back to the original reference.
20
21 */
22
23 public class StringTest {
24
25 public static void main(String[] args) {
26
27 String str1 = "Hi there";
28
29 String str2 = new String("Hi there");
30
31 // Display true if str1 and str2 have the value
32
33 System.out.println(str1.equals(str2));
34
35 // A new uppercase version of str1
36
37 System.out.println(str1.toUpperCase());
38
39 // A new lowercase version of str2
40
41 System.out.println(str1.toLowerCase());
42
43 System.out.println(str1.substring(1,4));
44
45 // A new version of str1 w/o any trailing whitespace chars
46
47 System.out.println(str1.trim());
48
49 // Display true if str1 start with "Hi"
50
51 System.out.println(str1.startsWith("Hi"));
52
53 // Display true if str1 ends with "there"
54
55 System.out.println(str1.endsWith("there"));
56
57 // Replace all i's with o's
58
59 System.out.println(str1.replace('i', 'o'));
60
61 }
62
63 }
64
65
main() 方法
要在命令行中作为应用程序运行的 Java 类必须定义一个 main() 方法才能运行。在 Java 代码中, main() 方法遵循一个严格的命名约定。您可以按照下面的方式声明 main() 方法:
2
注意: 您可以保留 public 和 static 修饰符,您也可以将 String 数组命名为任何您喜欢的名字。然而要记住上面的格式是常规的用法。并不是所有的类都需要一个 main() 方法 —— 只有那些从命令行中运行的程序才需要。一个典型的 Java 应用程序有一个具有 main() 方法的类和其他几个没有 main() 方法的支持类。
包
像 Java 这种面向对象的语言有助于促进类的重用。由于大部分程序员在自己的类中都使用非常简单的描述性名字(例如 Invoice 或 User ),因此在重用他人提供的资源时命名发生冲突的可能性就会很高。Java 语言通过让每一个类都属于一个 包 来解决这个问题。您可以同时使用不同包中的同名类。要将一个类与一个包关联在一起,您必须在类的源代码中的第一行就使用 package 语句进行声明。下面是一个例子:
2
按照约定,您的包名的前缀要采用 Internet 域名反转的形式(例如 com.yourco.somepackage )。要使用其他包中的类,您有两种选择。第一种选择是使用该类的全名,其中包括包名。清单 6 给出了一个例子。
清单 6. 使用完整的类名
2
3 public static void main(String[] args) {
4
5 Java.util.Date today = new java.util.Date();
6
7 System.out.println("The date is " + today);
8
9 }
10
11
另外一种方法是在源代码文件中对其他包中的类使用一个 import 语句。这样就不再需要全名了,如清单 7 所示。
清单 7. 使用 import 语句
2
3 public class PackDemo1 {
4
5 public static void main(String[] args) {
6
7 Date today = new Date();
8
9 System.out.println("The date is " + today);
10
11 }
12
13
您可以使用通配符来导入一个包中的所有类。如果您需要使用同一个包中的多个类,这种功能就会非常有用,如清单 8 所示。
清单 8. 使用带有通配符的 import 语句
2
3 public class PackDemo1 {
4
5 public static void main(String[] args) {
6
7 Date now = new Date();
8
9 System.out.println("The date is " + today);
10
11 }
12
13
包的重用
在 Visual Basic 中,您可以先编写一些代码,并将其编译为动态链接库(DLL),所谓动态链接库就是文件系统中一个扩展名为 .dll 的文件。其他程序可以通过引用这些 DLL 来使用其中包含的代码。Java 语言还允许您将多个类文件打包成称为 Java 档案包(JAR)的文件,以便易于重用。具有 .jar 扩展名的文件是一种标准的压缩文件,可以使用 WinZip 或其他压缩工具进行维护。然而,为了方便起见,Java SDK 包含了一个名为 jar.exe 的工具(在 Windows 平台上),您可以使用这个工具将多个类打包到一个 .jar 文件中。
在我们向您介绍一个使用 jar.exe 工具的例子之前,重要的一点是您需要理解包名与 Java 平台用来构建类并在运行时装入类时所使用的目录结构有关。考虑一个名为 Test 的类,其源代码文件名为 Test.java。如果您将 Test.java 定义成包 com.mycompany.test 的一部分,那么编译器就为生成的 .class 模块创建一个目录树。这个目录树是根据包名生成的,在本例中这个目录树是 com\mycompany\test,其中包名中的小数点被转换为一级级的目录。
现在,请打开一个命令提示符,并创建一个目录(例如 c:\javapack)。然后将当前路径切换到该目录中( cd javapack ),并使用您喜欢的文本编辑器将清单 9 中的代码添加到一个名为 Test.java 的新文件中。
清单 9. 使用包的例子
2
3 public class Test
4
5 {
6
7 public static void main(String[] args) {
8
9 System.out.println("In test");
10
11 }
12
13 }
14
15
现在,使用下面的命令编译 Test.java( -d 选项应该指向您刚才为本例创建的目录):
现在在 c:\javapack 目录中应该已经有了一个名为 com 的子目录。实际上,您可以看到 comTest.class 文件的完整名,该文件是在对 Test.class 编译时产生的。注意包名( com.mycompany.test )如何被转换成相应的目录结构(com\mycompany\test),该目录结构相对于您刚才使用 -d 选项指定的目录。
现在,我们将向您展示 Test.class 如何才能更易于其他类重用。在 c:\javapack 目录中运行这个命令:
2
这个命令会创建一个文件,文件名为 Test.jar,其中包含了 com 子目录中的所有类。
运行下面这个命令,使用 Test.jar 文件中的类:
2
注意您只能使用全名才能在命令行中运行这个命令,还要注意使用 -classpath 选项指向 Test.jar 的方法。另外,您可以将 Test.jar 文件加入 CLASSPATH 环境变量中, CLASSPATH 环境变量是一个使用冒号分割的列表,每一项的内容是 JAR 文件或目录,Java 编译器和 JVM 都会使用这个环境变量来查找要装载的类。
其他区别
我们已经了解了 Java 语言 与 Visual Basic 之间主要的一些语法区别,它们之间还有以下一些区别:
全局变量:与 Visual Basic 不同,Java 语言并不提供声明全局变量(或方法)的方法。
GoTo : 虽然 Java 语言保留了 goto 作为一个关键字,但是它并没有类似于一个 Visual Basic 用法的 Goto 语句。
自由放置变量:您根据需要可以在任何地方声明 Java 变量。您并不需要集中声明变量,但是在 Visual Basic 中必须如此。
继承:Visual Basic 并不会让您定义对其他类的功能进行扩展的类。Java 语言可以让您定义一个继承除超类私有成员之外的部分的类。这些新类可以对所继承的类进行扩展,也可以重载所继承的成员的一些行为。(在下一节中您将了解更多有关继承的内容。)