第一次:Java的语言基础
Java语言是目前最受欢迎的程序语言之一,与传统的程序语言相比(比如C、C++),Java语言简单易学,使用它编程时间短、功能强,人们接受起来也更快、更简便。Java主要具有以下三个特点:
第一, 跨平台,不管Windows还是Unix或者其他平台,它都可以使用;
第二, 面向对象;
第三, 动态域的控制。
1.1 初识Java语言
像其它编程语言一样,Java编程语言也被用来创建应用程序。那,首先我们还是从一个最普遍的小应用程序范例来切入——在屏幕上显示字串“Hello World!”。下列代码给出了这个Java应用程序。
1.1.1 HelloWorldApp
1.//
2.// Sample HelloWorld application
3.//
4.public class HelloWorldApp{
5.public static void main (String args[]) {
6.System.out.println ("Hello World!");
7.}
8.}
以上程序行是在你的屏幕上打印“Hello World!”所需的最少组件。接下来,我们就针对上面给出的这段程序来简单解释一下,并且来实际编译、运行它。
1.1.2 描述HelloWorldApp
第1-3行
程序中的1-3行是注释行
1 //
2 // Sample HelloWorld application
3 //
第4行
第4行声明类名为HelloWorldApp。类名(Classname)是在源文件中指明的,它可在与源代码相同的目录上创建一个classname.class文件。在本例题中,编译器创建了一个称为HelloWorldApp.class的文件, 它包含了公共类HelloWorldApp的编译代码。
4 public class HelloWorldApp{
第5行
第5行是程序执行的起始点。Java技术解释器必须发现这一严格定义的点,否则将拒绝运行程序。
其它程序语言(特别是C和C++)也采用main ()声明作为程序执行的起始点。此声明的不同部分将在本课程的后几部分介绍。
如果在程序的命令行中给出了任何自变量,它们将被传递给main()方法中被称作args的String数组。在本例题中,未使用自变量。
5 public static void main (String args[]) {
- public-方法main()可被任何程序访问,包括Java技术解释器。
- static- 是一个告知编译器main()是用于类HelloWorldApp中的函数的关键字。为使main()在程序做其它事之前就开始运行,这一关键字是必要的。
- void- 表明main()不返回任何信息。这一点是重要的,因为Java编程语言要进行谨慎的类型检查,包括检查调用的方法确实返回了这些方法所声明的类型。
- String args [] - 是一个String数组的声明,它将包含位于类名之后的命令行中的自变量。
java HelloWorldApp args[0]args[1]····
第6行
第6行声明如何使用类名、对象名和方法调用。它使用由System类的out成员引用的PrintStreamout对象的println()方法,将字串“Hello World!”打印到标准输出上。
6 System.out.println (“Hello World!”);
在这个例子中,println()方法被输入了一个字串自变量并将其写在了标准输出流上。
第7-8行
本程序的7-8行分别是方法main()和类HelloWorldApp的下括号。
7 }
8 }
1.1.3 编译并运行HelloWorldApp
编译
当你创建了HelloWorldApp.java源文件后,用下列程序行进行编译:
c:\student\javac HelloWorldApp.java
如果编译器未返回任何提示信息,新文件HelloWorldApp.class则被存储在与源文件相同的目录中,除非另有指定。
运行
为运行你的HelloWorldApp应用程序,需使用Java解释器和位于bin目录下的java:
c:\student\ java HelloWorldApp
Hello World!
1.1.4 严格的约定
通过上面实际编写、编译和运行这个简单的例子,我们会发现Java是一种限制很严格的语言。我们在编写Java程序的时候,一定要严格遵从它的约定,以后你会发现这些约定对维护和组织程序,使你养成一种优良的编程风格都很有帮助。
->; 源文件的类型
在Java中,一个源程序文件被称为一个编译单元。它是一个包含一个或多个类定义的文本文件。Java编译器要求源程序文件必须使用.java文件扩展名。这里可以注意到这个文件的扩展名是4个字符,所以,你的操作系统必须要有支持长文件名的能力。
->; 源文件的命名
如果.java文件包括一个公共类,那么它必须使用与那个公共类相同的文件名。例如在前例中的类的定义是
public class HelloWorldapp
源文件名则必须是HelloWorldapp.java
->; 类的数量
在源文件中,可以定义多个类,但每次只能定义一个公共类。
->; 标识符
Java中使用的标识符可以是大写和小写字母、数字、下划线(_)、美元符号($)的任意组合。以下是一些有效的标识符:
Year99 count this_is_ok $some
以下是一些无效的标识符:
99year hello# not/ok
这里需要提醒大家注意的是,Java是一种大小写敏感的语言,所以大家在书写代码的时候一定要注意大小写的运用。
1.2 结构与构件现在,我们从一个典型的Java源文件来了解一下Java程序涉及到的一些重要的构件,以及这些构件的结构。
1 package trades;
2 import java.util.Vector;
3 public class Quote extends Thread implements Tradable {
4 // Code goes in here
5 }
那我们从上面的例子中可以发现源文件的结构主要包含三个要素:
->; 一个包声明(可选)
程序的第1行就是声明了一个包(package),把该程序放在这个包中间。
->; 任意数量的包引入语句(可选)
程序的第2行是要求该程序引入系统提供的一个包java.util.Vector。
->; 任意数量的类的声明
程序的3-5行则是声明了一个public的类Quote,它是从它的超类Thread扩展得到,并且实现Tradable的接口。
该三要素必须以上述顺序出现。即,任何包引入语句出现在所有类定义之前;如果使用包声明,则包声明必须出现在类和引入语句之前。
结合上面的例子,我们接下来简单的讨论一下涉及到的这些构件,包package、包引入import、类class、方法method和变量variable。
1.2.1 包package
包实际上就是一个组织类class和接口interface的集合。通过包的这种机制,来把类名空间划分成更多易于管理的块。这样做其主要目的就是可以避免类名的冲突,在不同的包里的类,其名字相同也不会发生冲突。包的主要功能如下:
->; 依照功能来组织和划分类。例如:java.awt包含了构成抽象窗口工具包(AWT)的类,这个包被用来构建和管理应用程序的图形用户界面。
->; 有助于定义变量和方法的访问控制。
->; 通过这种包和包引入的机制,也可以保持程序的相对独立性,有利于模块化程序设计的实现。
声明包的定义语句必须放在源文件的顶端。如果你没有显式的声明一个包,那么Java会把你的类放入缺省包(default package)里面,这个包没有名字。
Java使用文件系统目录来存储包,目录名必须和包严格的匹配。另外,这里还要简单谈论一下类路径(CLASSPATH)环境变量的问题。Java编译器使用参考的包层次的根是由类路径决定的。例如,你可以在DOS系统环境下使用如下的命令来指定类路径:
set CLASSPATH=C:\Mysource;C:\Mypackages
如果我们在源文件类的声明前有以下语句:
Package trades.quotes
那么,这个源文件就放在下面这个目录里面:
c:\Mypackages\trades\quotes
最后,需要提醒的是,如果你定义的类已经指定到了某个包中,那么在运行的时候你也需要指定相应的包名和类名一起使用。
同学们可以结合实验二来加深对包概念的理解。
1.2.2 类class
类是面向程序设计中最小的抽象单元,它就像是一个数据和代码的容器。它也是Java里面最重要的一个要件。它通过实例化转变为对象,在实例化的时候自动调用构造函数来初始化对象。
对于类的声明比较复杂,它可以使用很多的修饰符,我们以下面的例子来简单谈论一下这些修饰符。
public abstract class Myclass extends Parent implements A,B {}
首先我们看到的public修饰符,是定义的类的访问控制属性,这个我们在下一章会有详尽的介绍。
然后我们看到的abstract修饰符是表示该类是个抽象类,需要其他类来扩展。这里再介绍一个final修饰符,它与abstract修饰符的意义正好相反,它表示该类不能扩展。所以abstract和final不能在声明类的时候同时使用。
在Java中所有的类都扩展一个超类,如果我们没有指定一个超类,那么系统会把Object类作为它要扩展的超类,Object类就是所有类的超类。这里需要注意的是,在C++中我们使用基类(base class)和继承类(derived class)的称谓,而在Java中我们一般称为超类(super class)和子类(subclass)。
另外,需要提一下的是一个特殊的关键字this,它用来引用正在被调用方法的所属当前对象。
1.2.3 接口interface
接口是一个非功能性、抽象的类,它包含常量和没有功能性的方法声明。也就是说,用interface,你可以指定一个类必须做什么,而不是规定它如何去做。接口在语句的构成上与类十分相似,但是它们缺少实例变量,而且它们定义的方法是不含有方法体的。
接口中声明的变量,一般是final和static型的,意思是它们的值不能通过实现类而改变,也就是说它们被看作是常量,而且它们还必须以常量值初始化。
对于接口来说,它们定义以后都是需要类来实现implement的。也就是说,使用具体的类来实现上面的“如何做”。一个类可以实现多个接口,一个接口也可以被多个类来实现。
另外,接口也可以扩展其他接口来实现继承。如:
interface MyInterface extends YourInterface, Runnable {}
1.2.4 方法method
方法声明的是被调用执行的代码,它可以使用传递的参数并且返回一定类型的返回值。对于方法的修饰符也比较复杂和繁多。我们仍然以一个例子来简单谈论以下其中的一些修饰符。
public static final synchronized double getPrice ( final int itemCode, Color itemColor ) throw Exception { /* code here */}
首先,Public是定义的方法的访问控制属性,这个我们在下一章会有详细介绍。
然后,static、final和synchronized是特殊的修饰符。同样需要注意的是其中final和abstract修饰符不能同时使用的。
最后,我们可以看到该方法getPrice返回一个double数据类型的返回值,而且里面定义了两个参数(itemCode和itemColor)。
另外,我们还注意它通过throw修饰符,表示它会抛出一个Exception的异常,关于异常我们在后面的章节会介绍到。
接下来我们会介绍两种比较特殊的方法。
->; Main方法
Main()方法是Java程序的入口起点,它和其他方法的定义类似,只是它包含一个字符串数组用来传递命令行方式执行程序时所跟的参数。如下的例子它把命令行方式所跟的参数全部显示出来:
public class MainTest {
public static void main ( String [] args ) {
for ( int i = 0 ; i < args.lenth; i++ ) {
System.out.println(“Argument ” + i + “: ” + args[i] );
}
}
}
执行如下:
c:\java project\Main>; java MainTest Philip K Dick
Argumet 0: Philip
Argumet 1: K
Argumet 2: Dick
这里需要注意的是,如果Main()方法没有使用static修饰符,那么编译不会出错,但是如果你试图执行该程序将会报错,提示main()方法不存在。这是因为你如果这样使用命令行的形式直接执行该程序,MainTest类并没有实例化,所以其main()方法也不会存在,而使用static修饰符则表示该方法是静态的,不需要实例化即可使用。
->; 构造函数Constructor Method
当类被实例化的时候,第一个被调用的方法就是构造函数。构造函数的主要作用就是初始化变量。如果没有定义构造函数,那么Java会使用其超类的默认构造函数。
构造函数与其他方法相比,主要具有以下的特点:
->; 构造函数的名字和其类名相同。
->; 没有返回值。
->; 构造函数不能像其他超类的方法那样被继承。
->; 不能使用final、abstract、synchronized、native或者static修饰符。
有时候,我们在编写构造函数的时候,可能需要首先调用其超类的构造函数,这里我们使用super的关键字,实际上它同this关键字的作用类似,只是它指的是其超类。如下的例子:
class DataServer extends Server {
public String serverName;
public DataServer ( int startCode ) {
super ( startCode );
serverName = “Customer Service”;
}
}
需要注意的是,调用超类构造函数super()的语句必须放在其构造函数定义的前面,否则编译器会报错。
1.2.5 变量variable
变量是Java程序的一个基本存储单元。变量由一个标识符、类型及一个可选初始值的组合定义。此外,如同定义方法一样,它也有各种的修饰符。比如访问控制属性的修饰符public、private、protected和final、static等。这里需要注意的是,变量不能使用synchronized、abstract和native修饰符。
在定义变量的时候需要指明其类型,除了常用的基本类型(比如int型、Boolean型等)以外,也可以使用对象类型。
1.2.6 引入语句import
使用import引入语句是允许你选择某个包中的某个类或者所有类,使之能在你当前的代码中能方便的使用。例如:
import java.util.Dictionary; //引入java.util包中的Dictionary类
import javax.swing.*; //引入javax.swing包中的所有的类
当然如果你不使用引入语句也可以使用其他包中的其他的类,只要你指定引用对象的全名。比如:
java.util.Date now = new java.util.Date();
另外,java.lang包是会被自动引入到源程序中的。(