Java高手真经·编程基础卷:Java核心编程技术
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第1课 Java快速上手

在学习Java之前,首先让我们来解释一个问题——Java是什么?Java是一种跨平台的程序设计语言,用来开发运行于网络上的各种应用程序,能够在各种操作系统上运行。显然这个解释过于专业,难以让初学者理解。

如果要用一个词语来概括Java的真正内涵,那就是“海纳百川,有容乃大”!海——代表Java资源平台,百川——代表广大的软件开发者,容——代表Java的开放特性,即开源、跨平台、跨网络。Java的独特魅力就是其开放性,正因为此:

● 它已经吸引了全球最大的开发者队伍——500万开发者,这是全球最大的、最具活力的开发团队。

● 目前采用Java的设备也已超过45亿,其中包括8亿台个人计算机、15亿部移动电话及其他手持式设备、22亿个智能卡,以及机顶盒、打印机、网络照相机、游戏、汽车导航系统、彩票终端、医疗设备、收费站等。

Java可以说是无处不在,其市场占有率也在逐年上升。TIOBE是一个专业化的软件评估公司,它每月都会根据工程师、培训课程、技术公司数量,对各语言的市场占有率进行统计并发布报告(http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html),如表1-1所示。

表1-1 各语言占有率

Tips

其中,状态中的A表示为主流开发语言,B为非主流开发语言,A-介于A和B之间。该报告不表示哪一种语言是最好的,但是能够作为系统选型时的参考和市场趋势的预测。该报告也被Google、MSN、Yahoo!和YouTube所引用参考。

表1-1列出了前20位的语言,除此之外还有上百种语言,常用的如Fortran、MATLAB、FoxPro、Transact-SQL、Awk、Groovy、Eiffel、PowerBuilder、VBScript、XSLT等。从表中可以看出,排名前十位的语言分别是:Java、C、C++、PHP、Visual Basic、Perl、Python、C#、JavaScript、Ruby,它们都是目前市场上的主流语言。其中,Java语言排在第一位,拥有1/5以上的市场占有率。

在以上的各种语言中,面向对象语言如Java、C++等占有率最高,其次是面向过程语言,如C、Pascal等,统计数据如表1-2所示。

表1-2 语言分类占有率

了解了Java在市场中的位置,下面就带你迈入Java技术之门。这里是学习Java技术的第一站,在本章将介绍概括性的知识,了解Java的特性和机制,并开发第一个程序HelloWorld,共分为如下3部分。

● 开始了解Java:包括Java语言的11个特性、构成(JIT、JVM、JRE、JDK)、Java虚拟机JVM。

● 安装Java开发环境:JDK的下载、安装、配置和使用。

● 开发第一个Java程序——HelloWorld.java:包括开发、编译、运行、打包和生成API文档。

本课将通过了解、安装、开发3步的讲解,帮助你稳健、扎实、有效地迈进Java的精彩世界。

1.1 开始了解Java

Java是Sun公司推出的面向对象程序设计语言,特别适合于Internet应用程序开发,它的最大特点就是“一次编写,到处运行”。下面我们就来了解Java语言的特性和运行机制。

1.1.1 Java语言的11个特性

Sun公司在1995年推出Java时发布了一个Java白皮书,并这样定义Java语言:Java是一种简单的(Simple)、面象对象的(Object-Oriented)、分布式的(Distributed)、解释的(Interpreted)、健壮的(Robust)、安全的(Secure)、结构中立的(Architecture-neutral)、可移植的(Portable)、高性能的(High-Performance)、多线程的(Multi-Threaded)、动态的(Dynamic)语言。

通过这11个词语来概括Java语言的特性,下面来看看每一个词语所代表的含义。

(1)简单的(Simple)

● 风格类似于C++,基本语法与C语言类似。

● 摒弃了C++中容易引发程序错误的地方,如指针和内存管理。

● 提供了丰富的类库。

(2)面象对象的(Object-Oriented)

支持静态和动态风格的代码继承及重用,是完全面向对象的,它不支持类似C语言那样的面向过程的程序设计技术。

(3)分布式的(Distributed)

Java包括一个支持HTTP和FTP等基于TCP/IP协议的子库。因此,Java应用程序可凭借URL打开并访问网络上的对象,其访问方式与访问本地文件系统几乎完全相同。

(4)解释的(Interpreted)

Java解释器(运行系统)能直接运行目标代码指令。

(5)健壮的(Robust)

● Java致力于检查程序在编译和运行时的错误。

● 类型检查帮助检查出许多开发早期出现的错误。

● Java自已操纵内存减少了内存出错的可能性。

● Java还实现了真数组, 避免了覆盖数据的可能。

(6)安全的(Secure)

Java的安全性可从两个方面得到保证。一方面,在Java语言里,指针和释放内存等C++功能被删除,避免了非法内存操作;另一方面,当Java用来创建浏览器时,语言功能和一些浏览器本身提供的功能结合起来,使它更安全。

(7)结构中立的(Architecture-neutral)

Java源程序被编译成一种高层次的与机器无关的byte-code格式语言,被设计在Java虚拟机上运行。

(8)可移植的(Portable)

Java应用程序可以在配备了Java解释器和运行环境的任何计算机系统上运行,通过定义独立于平台的基本数据类型及其运算,Java数据得以在任何硬件平台上保持一致。

(9)高性能的(High-Performance)

Java可以在运行时直接将目标代码翻译成机器指令,Sun用直接解释器1秒钟内可调用300000个过程,翻译目标代码的速度与C/C++的性能没什么区别。

(10)多线程的(Multi-Threaded)

Java提供的多线程功能使得在一个程序里可同时执行多个小任务。多线程带来的好处是可以有更好的交互性能和实时控制性能。

(11)动态的(Dynamic)

Java的动态特性是其面向对象设计方法的拓展,它允许程序动态地装入运行过程中所需要的类。

1.1.2 Java语言的构成——JIT、JVM、JRE、JDK

下面我们来了解Java的构成。所谓Java的构成,是指Java运行环境的组成,从核心到外围包括JIT、JVM、JRE、JDK,如图1-1所示。

图1-1 Java构成图

JDK、JRE、JVM、JIT四者的区别如下。

● JDK是Java Develop ToolKit的缩写,它里面有很多用Java所编写的开发工具(如javac.exe、jar.exe等),还包括一个JRE的调试环境。如果安装了JDK,会有两套JRE,一套位于\jre目录下,另外一套位于C:\Program Files\Java目录下,后面这套比前面那套少了Server端的Java虚拟机,不过,直接将前面那套的Server端Java虚拟机复制过来就行了。

● JRE是Java Runtime Environment的缩写,是Java运行的基础,它提供了Java运行的API,Java程序必须有JRE才能运行。

● JVM是Java Vitual Machine的缩写,它是Java程序运行的虚拟机环境,JRE目录下的Bin目录有两个目录,即server与client,这就是真正的jvm.dll所在。jvm.dll无法单独工作,当jvm.dll启动后,会使用explicit的方法,而这些辅助用的动态链接库(.dll)都必须位于jvm.dll所在目录的父目录之中。因此想使用哪个JVM,只需要设置PATH,指向JRE所在目录下的jvm.dll。

● JIT是Java In Time的缩写,即Java即时编译器,是JVM的一部分,属于内核部分。

其中的JVM是Java运行的虚拟机环境,它是Java运行环境的重要一环,JDK是Sun公司开发的Java开发工具包,在后文中我们都将逐步讲解。

1.1.3 Java虚拟机JVM

JVM是Java虚拟机(Java Virtual Machine)的缩写,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬件架构,具体如下。

● JVM指令系统。

● JVM寄存器。

● JVM栈结构。

● JVM碎片回收堆。

● JVM存储区。

Java语言最突出的特点就是可以在任何操作系统中运行。使用Java虚拟机就是为了支持与操作系统无关,在任何系统中都可以运行。Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。

如图1-2所示,展示了JVM在Java类文件(即字节码文件class)和操作系统中间的作用。

图1-2 JVM模拟图

可以说,Java虚拟机是Java语言的基础,它是Java技术的重要组成部分。

1.2 安装Java开发环境

Java类文件的生成和在JVM里的运行,都是通过JDK开发工具来执行的,JDK提供了一系列的开发运行命令,下面我们就来讲解JDK开发环境的安装与使用。

1.2.1 下载JDK

JDK(Java Development Kit)即Java开发工具包,它是进行Java开发的必备工具包,包含了Java运行时环境JRE、Java虚拟机JVM和Java运行API,为我们进行Java的开发工作提供了必备的运行环境和API接口。

JDK的官方网站是http://java.sun.com/javase/downloads/index.jsp,如图1-3所示。

图1-3 JDK官方网站

该页面提供了JDK各版本的下载,从该页面中可以看到最新的版本为JDK 6,本书也使用当前最新的版本JDK 6进行开发。单击“Download”按钮即可进入到下载页面,按照页面提示最后会下载到安装文件jdk-6u10-beta-windows-i586-p.exe,其中6u10表示JDK 6的第10次更新。

1.2.2 安装JDK和JRE

刚才下载的安装包jdk-6u10-beta-windows-i586-p.exe是JDK的安装包,它包含了JDK和JRE的安装程序,JDK是程序员开发时所需要的工具集,JRE是程序运行时环境,因此对于开发人员来说都需要安装JDK和JRE,而对于部署机器来说可以下载专门的JRE包来安装。由于我们要进行Java程序的开发,因此下载了该JDK包。

安装该JDK包共需要如下的8个步骤。

(1)安装欢迎页面:双击下载的jdk-6u10-beta-windows-i586-p.exe文件,可进入安装欢迎界面,如图1-4所示。

图1-4 安装欢迎页面

(2)接受许可证协议:欢迎页面打开后会计算该安装包的大小,然后会显示“下一步”按钮可用,此时单击“下一步”按钮弹出许可证协议界面,如图1-5所示。

图1-5 接受许可证协议

(3)选择安装的可选功能:要继续安装,必须单击“接受”按钮,即可进入功能选择界面。该界面列出了安装包所包含的功能组件,可以通过单击某一个功能组件的下拉按钮来决定是否安装该组件,默认情况下我们都安装这些组件,因此不需要进行选择,如图1-6所示。

图1-6 选择安装的可选功能

(4)更改JDK安装目录:默认情况下JDK的安装目录为C:\Program Files\Java,通常我们为了方便找到JDK目录,可以自己指定JDK安装目录。单击图1-6中的“更改”按钮,即可弹出选择安装目录的界面。我们更改目录为D:\jdk1.6.0-10\,如图1-7所示。

图1-7 更改JDK安装目录

(5)开始安装进程:单击图1-7中的“确定“按钮,即可进入如图1-8所示的安装进程界面。

图1-8 开始安装进程

(6)选择JRE安装目录:在该安装过程中会进行下载、解压缩等一系列操作,完成后会显示如图1-9所示的JRE安装界面。在该界面中同样包含一个“更改“按钮,用来选择JRE的安装目录。由于JRE属于系统运行时环境,所以我们使用默认的参数C:\Program Files\Java\jre6\即可。

图1-9 选择JRE安装目录

(7)开始安装JRE:单击图1-9中的“下一步“按钮,即可进入如图1-10所示的安装JRE进程界面。

图1-10 开始安装JRE

(8)安装完成:该过程结束后即完成了JDK和JRE的安装,此时会显示如图1-11所示的安装完成界面。

图1-11 安装完成

到此,JDK和JRE的安装就结束了,JDK安装后的目录结构如图1-12所示。这些目录分别对应JDK以下部分的组成。

图1-12 JDK安装后的目录

● bin——开发工具:位于bin子目录中。指工具和实用程序,可帮助你开发、执行、调试和保存以Java编程语言编写的程序。

● demo——演示applet和应用程序:位于demo子目录中。带有源代码的Java平台编程示例,包括使用Swing和其他Java基类,以及Java平台调试器体系结构的示例。

● include——C头文件:位于include子目录中。支持使用Java本机界面、JVMTM工具界面,以及Java 2平台的其他功能进行本机代码编程的头文件。

● jre——运行时环境:位于jre子目录中。Java运行时环境的实现,由JDK使用。该运行时环境包含Java虚拟机、类库及其他文件,可支持执行以Java编程语言编写的程序。

● lib——附加库:位于lib子目录中。开发工具需要的附加类库和支持文件。

● sample——样例代码:位于sample子目录中。包含某些Java API的编程样例(带源代码)。

● src.zip——源代码:位于src.zip中。组成Java 2核心API的所有类的Java编程语言源文件(即java.*、javax.*和某些org.*包的源文件,但不包括com.sun.*包的源文件)。此源代码仅用于提供信息,以便帮助开发者学习和使用Java编程语言。这些文件不包含特定于平台的实现代码,且不能用于重新生成类库。要对这些文件进行解压,请使用任一常用的zip实用程序;或者也可以使用JDK的bin目录中的Jar实用程序:

            jar xvf src.zip

1.2.3 设置环境变量

在“我的电脑”上单击鼠标右键,在弹出的快捷菜单中选择“属性”命令,在弹出的对话框中选择“高级”选项卡,单击“环境变量”按钮,显示“环境变量”窗口,如图1-13所示。

图1-13 “环境变量”窗口

然后单击“新建”按钮添加如下的环境变量。

① 设置JAVA_HOME变量为Java的主目录C:\j2sdk1.6.0:

            $JAVA_HOME=C:\j2sdk1.6.0;

如图1-14所示为设置JAVA_HOME变量。

图1-14 设置JAVA_HOME变量

Tips

设置JAVA_HOME的目的是,许多其他的软件都以该变量来查找Java的安装路径,例如Tomcat,设置了该环境变量,Tomcat就能够自动查找到Java安装路径了。

② 把Java的bin目录路径C:\j2sdk1.6.0\bin添加到Path环境变量中:

            $Path=C:\j2sdk1.6.0\bin;

如图1-15所示为设置PATH变量。

图1-15 设置PATH变量

Tips

设置Path的目的是,可以在任意位置下执行JDK的相关命令,如编译javac、运行Java等。

测试Java环境:进入命令提示符(选择“开始”→“运行”命令,在打开对话框中输入“cmd”),然后输入命令“javac -version”或“java -version”,查看版本是否正确,正常情况下会显示如图1-16所示的信息。

图1-16 查看版本号

输入“javac -help”查看是不是正确的提示,如果提示“不是内部或外部命令,也不是可运行的程序或批处理文件”,则说明没有把Path路径设置好。正常情况下应该显示如图1-17所示的窗口。

图1-17 查看帮助

1.2.4 学会查找Java帮助和API文档

Sun在其官方网站上提供了一系列的帮助文档,包括核心和非核心API文档、开发手册等,网址为http://java.sun.com/javase/reference/api.jsp,如图1-18所示。

图1-18 Sun网站上帮助文档列表

从该页面上可以看到各个版本的API帮助文档和开发手册,包括1.3.0、1.3.1、1.4.0、1.4.2、5.0、6.0。从JDK 5.0开始,就提供了3个语言版本的API文档,包括英文、中文、日文。中文API地址为http://gceclub.sun.com.cn/Java_Docs/jdk6/html/zh_CN/api/index.html,如图1-19所示。

图1-19 API文档

该页面提供了Java核心API的帮助文档,使用JDK开发Java应用程序时,通常需要引用一些核心的API类,此时都需要在这里查找类的方法列表和使用说明。它共包含3部分:

● 左上角是类包列表。

● 左下角是类列表,选择左上角的类包,在下方就会显示该包下的类列表。

● 右侧是类的函数列表,选择左下角的某一个类后就会显示类的函数列表。

Tips

Java API文档相当于微软的MSDN,是Java程序员的必备手册。因此,你必须学会使用该API文档来查找Java类的函数。

1.3 开发第一个Java程序——HelloWorld.java

Java是一门很容易上手的语言,本节我们将通过一个入门实例HelloWorld.java,来讲解一个Java类的编写、编译、运行、打包和生成API文档的方法。

Tips

使用命令行编译、运行、打包和生成API文档,是学习Java编程的基本功,掌握了这些方法,以后无论是在使用Eclipse、Ant等什么工具,或者在Linux系统下的使用,都是基于这些命令的。

1.3.1 编写Java入门实例HelloWorld.java

首先我们需要建立一个工作目录D:\demo,接下来的工作都将在该目录下进行。在该目录下新建一个子目录mypackage,它将被用为类的包目录。

然后在mypackage目录下新建第一个Java类文件HelloWorld.java,作用是往控制台输出一个字符串“Hello World!”。先来看看该类的完整代码,如程序1-1所示。

程序1-1 HelloWorld.java完整版

                11 package mypackage;
                2
                3  /**
                4   *@author liuzhongbing lzb_box@163.com
                5   */
                62 public class HelloWorld{
                7
                8      /**
                9      * 变量
                10      */
                113private String world="World";
                12
                13     /**
                14      * 函数
                15      */
                164    public void say(){
                175        System.out.println("Hello"+world+"!");
                186    }
                19
                20     /**
                21      * 执行入口函数
                22      *@param args
                23      */
                247    public static void main(String args[]){
                25         //创建类的实例
                268        HelloWorld inst=new HelloWorld();
                27
                28         //调用函数
                299        inst.say();
                2010        }
                3111    }

该类共包含31行代码,去掉注释和空行后只有11行代码,也就是说只有11行有效代码,如程序1-2所示。

程序1-2 HelloWorld.java精华版

                1  package mypackage;
                2  public class HelloWorld{
                3  private String world="World";
                4      public void say(){
                5          System.out.println("Hello"+world+"!");
                6      }
                7      public static void main(String args[]){
                8          HelloWorld inst=new HelloWorld();
                9          inst.say();
                10    }
                11}

为了提高代码的可读性,我们增加了很多注释和空行,这也是编写Java代码所需要遵守的编码规范(在第4章中我们将会详细讲解Java编码规范)。

另外,该类是一个简单、涵盖比较全的Java类。简单,是因为它的语法类似于C++;全面,是因为该类基本上覆盖了Java类的大部分元素,包括如下。

● 包元素:第1行的“package mypackage”,指示该类的包为mypackage,所以该类应该放在当前目录的mypackage子目录(即包)中。

Tips

当前目录是Java中运行程序的根目录,任何一个程序、应用都有一个根目录,相对该根目录可以放置多个包。另外,包里还可以有子包,即包的继承。例如,可以定义第二层包mypackage.childpackage。

● 类元素:第2行的“public class HelloWorld”定义了一个共用的(public)类(class)HelloWorld,类文件的命名需要与该类名相同。

● 变量:第3行的“private String world = "World";”定义了一个私有的(private)字符串类型(String)的变量world,该变量将会被下一个函数引用。

● 函数:第4行的“public void say()”定义了一个共有的(public)的无返回参数(void)的函数say(),该函数中调用了系统类(System)的输出命令,往控制台输出一个字符串,并且引用了第3行定义的变量world。

● 入口函数:第7行的“public static void main(String args[])”定义了该类的执行入口函数,该入口函数类似于C代码中的入口函数main(),是程序执行的入口点。入口函数的修饰符必须是“public static void”,在后文中将会深入讲解。函数中我们创建了类HelloWorld的一个实例inst,然后调用该实例的函数say()来执行输出。

Tips

对于未学习过Java的人来说,也许以上的有些元素类型不太熟悉,先不用深究每一个元素是怎么使用的,在后面的章节中将会分专题讲解,我们先理解这个类的5个元素及各自的关系和作用就可以了,然后来学习如何编译和运行这个类。

1.3.2 编译类文件——javac命令

前文中我们讲到Java是“一次编写,到处运行”的,即跨平台运行的特性,这是由于它能够通过JVM来运行二进制代码文件,即.class文件。在一个类能够运行之前,都必须进行编译,被编译后的类文件为同名的文件,且以.class为文件扩展名。如HelloWorld.java会被编译为HelloWorld.class,类的编译和命名都是由编译命令javac自动完成的。

下面分4个方面来讲解javac命令的使用。

(1)javac命令的语法结构

javac命令的语法结构如下所示:

            javac [options] [sourcefiles] [@files]

其中的参数可按任意次序排列。

● options:命令行选项。

● sourcefiles:一个或多个要编译的源文件(例如HelloWorld.java)。

● @files:一个或多个对源文件进行列表的文件。

(2)传递源文件名的两种方法

以上编译命令的第二个和第三个参数分别对应了两种使用方法,用于将源代码文件名传递给javac。

● 使用sourcefiles:如果源文件数量少,在命令行上列出文件名即可。例如,对于MyClass1.java和MyClass2.java,可以使用“javac MyClass1.java MyClass2.java”进行编译,也可以使用通配符“javac MyClass*.java”。

● 使用@files:如果源文件数量多,则将源文件名列在一个文件中,名称间用空格或回车行来进行分隔。然后在javac命令行中使用该列表文件名,文件名前冠以@字符。例如我们可以命名一个文件@list.txt,然后执行“javac @list.txt”即可,此时的文件列表可以如下所示:

            MyClass1.java
            MyClass2.java
            MyClass3.java

(3)传递带包名的源文件的方法

对于有包路径的类,可以使用相对路径表示,比如包mypackage下的HelloWorld.java,可以使用“javac mypackage\HelloWorld.java”来编译,如图1-20所示。此时就会在包mypackage下产生编译后的文件HelloWorld.class。

图1-20 编译类文件

(4)命令选项

编译器有一批标准选项,目前的开发环境支持这些标准选项,将来的版本也将支持它。还有一批附加的非标准选项是目前的虚拟机实现所特有的,将来可能要有变化。非标准选项以-X打头。

以下3个是设置路径的选项。

● -classpath类路径:设置用户类路径,它将覆盖CLASSPATH环境变量中的用户类路径。若既未指定CLASSPATH又未指定-classpath,则用户类路径由当前目录构成。

● -d目录:设置类文件的目标目录。如果某个类是一个包的组成部分,则javac将把该类文

件放入反映包名的子目录中,必要时创建目录。例如,如果指定-dc:\demo并且该类名叫mypackage.HelloWorld,那么类文件就叫D:\demo\mypackage\ HelloWorld.class。若未指定-d选项,则javac将把类文件放到与源文件相同的目录中。

Tips

-d选项指定的目录不会被自动添加到用户类路径中。

● -sourcepath源路径:指定用以查找类或接口定义的源代码路径。与用户类路径一样,源路径项用分号(;)进行分隔,它们可以是目录、JAR归档文件或ZIP归档文件。如果使用包,那么目录或归档文件中的本地路径名必须反映包名。

Tips

通过类路径查找的类,如果找到了其源文件,则可能会自动被重新编译。

例如,我们可以使用这3个属性来将源代码、classpath和目标路径分开:

                javac -sourcepath src
                      -classpath classes:lib\Banners.jar \src\farewells\GoodBye.java
                      -d classes

这样,就会把src目录下的代码编译到classes目录下,并引用classpath中的类。

以下5个是设置编译属性和性能的选项。

● -deprecation:显示每种不鼓励使用的成员或类的使用或覆盖的说明。如果没有给出-deprecation选项的话,javac将显示这类源文件的名称,这些源文件使用或覆盖不鼓励使用的成员或类。

● -encoding:设置源文件编码名称,例如EUCJIS/SJIS。若未指定-encoding选项,则使用平台默认的转换器。

● -g:生成所有的调试信息,包括局部变量。在默认情况下,只生成行号和源文件信息。

● -nowarn:禁用警告信息。

● -verbose:冗长输出。它包括了每个所加载的类和每个所编译的源文件的有关信息。

除了以上几个常用的选项之外,还有一些联编选项和非标准选项(以-X开头的选项),这些选项不太常用,需要的读者可以查阅Java文档。

1.3.3 运行类文件——java命令

上面使用javac命令编译生成的*.class文件,需要使用java命令来运行它。使用java命令运行某一个类的条件是,该类必须包含有一个入口函数main(),如HelloWorld.java中的入口函数。java命令一次只可以执行一个类文件,找到该类文件的main()入口函数后即会开始执行代码。

下面分5个方面来讲解java命令的使用。

(1)java命令的语法结构

java命令的语法结构如下所示:

            java [options] class [argument]
            java [options] -jar file.jar [argument]

其中的参数意义如下。

● options:命令行选项。

● class:要调用的类名。

● file.jar:要调用的JAR文件名,只与-jar一起使用。

● argument:传给main函数的参数。

(2)执行一个类文件

执行类文件时,只需要指定类文件的全名即可,全名中包含包名,包路径使用点号“.”表示。例如,我们来编译前文中的mypackage\HelloWorld.class类,执行的命令如图1-21所示。

图1-21 运行类文件

此时就会调用HelloWorld.java的say()函数,往控制台输出一个字符串“Hello World!”。

(3)执行一个JAR包

执行JAR包时,该包中的MENIFEST.MF文件中必须指定当前包中那个类是主类,即指定执行入口类,使用属性为Main-Class(创建方法见下一节例4)。

执行的方式如图1-22所示。

图1-22 运行JAR包

(4)命令选项

java命令有一组标准选项,当前的运行时环境支持这些选项并且将来的版本也将支持它们。还有一组其他的非标准选项是特定于目前的虚拟机实现的,将来可能要有变化。非标准选项以-X打头。

● -classpath类路径:指定类的环境变量,同javac中的-classpath选项。

● -cp类路径:指定一个用于查找类文件的列表,它由目录、JAR归档文件和ZIP归档文件组成。类路径项用分号(;)分隔。指定-classpath或-cp将覆盖CLASSPATH环境变量的所有设置。

Tips

如果不使用-classpath和-cp,且没有设定CLASSPATH,则用户类路径由当前目录(.)构成。

● -D属性=值:设置系统属性的值。例如“-Dmyname=liuzhongbing”,这样在Java类中就可以取得系统属性myname的值liuzhongbing。

● -jar:执行封装在JAR归档文件中的程序。第一个参数是JAR归档文件的名称而不是启动类名。启动类由Main-Class清单头指定。JAR文件是所有用户类的源,其他的用户类路径设置将被忽略。

除了以上的几个常用选项外,还有一些以“-X”开头的非标准选项,用以对执行时的环境进行设置。最常用的是对Java虚拟机的堆大小进行设置,以提高Java运行的内存和运行效率。例如“-Xms256m -Xmx256m -XX:NewSize=128m -XX:MaxNewSize=128m”,Xms代表默认启动大小,Xmx代表最大大小,NewSize是新建对象的大小,MaxNewSize是新建堆运行增长的最大值,它决定了何时将新的对象置为旧的对象。其中m代表MB,g代表GB。

Tips

在进行Tomcat系统部署时,默认的内存大小为56MB,而通常我们可能需要更多的内存,此时就可以在Tomcat的启动命令后使用该参数。Tomcat也是通过java命令来执行一个Java类来启动的,因此此时可以添加“java … -Xms256M -Xmx128M”来加大内存,提高效率。

(5)给类传递参数

在Java的命令中还有一个变量argument,该变量用于向目标类main()函数传递输入参数,多个参数使用空格分隔。例如我们可以执行如下的传递参数的命令:

            java mypackage.HelloWorld  AAA  BBB

那么我们在入口函数中,就可以通过args变量来取得该参数:

            public static void main(String args[]) {
                String str1 = args[0];
                String str2 = args[1];
            }

1.3.4 类文件打包——jar命令

上文中我们讲到了运行JAR文件,下面我们就来讲解如何生成JAR包。

JAR包可以使用jar命令来创建。JAR工具是个Java应用程序,可将多个文件合并为单个JAR归档文件。JAR是个多用途的存档及压缩工具,它基于ZIP和ZLIB压缩格式。然而,设计JAR的主要目的是便于将Java Applet或应用程序打包成单个归档文件。将Applet或应用程序的组件(.class文件、图像和声音)合并成单个归档文件时,可以用Java代理(如浏览器)在一次HTTP事务处理过程中对它们进行下载,而不是对每个组件都要求一个新连接,这大大缩短了下载时间。JAR还能压缩文件,从而进一步提高了下载速度。此外,它允许Applet的作者对文件中的各个项进行签名,因而可认证其来源。

下面分4个方面来讲解jar命令的使用。

(1)jar命令的语法结构

jar命令的语法结构如下所示:

            jar{ctxu}[vfm0M][jar-文件][manifest-文件][-C目录] 文件名

(2){ctxu}属性

其中{ctxu}是jar命令的子命令,每次jar命令只能包含ctxu中的一个,它们分别表示如下。

● -c:创建新的JAR文件包。

● -t:列出JAR文件包的内容列表。

● -x:展开JAR文件包的指定文件或者所有文件。

● -u:更新已存在的JAR文件包(添加文件到JAR文件包中)。

(3)[vfm0M]选项

[vfm0M]中的选项可以任选,也可以不选,它们是jar命令的选项参数。

● -v:生成详细报告并打印到标准输出。

● -f:指定JAR文件名,通常这个参数是必需的。

● -m:指定需要包含的MANIFEST清单文件。

● -0:只存储,不压缩,这样产生的JAR文件包会比不用该参数产生的体积大,但速度更快。

● -M:不产生所有项的清单(MANIFEST)文件,此参数会忽略-m参数。

(4)参数

其他的参数意义如下。

● [JAR文件]:即需要生成、查看、更新或者解开的JAR文件包,它是-f参数的附属参数。

● [manifest文件]:即MANIFEST清单文件,它是-m参数的附属参数。

● [-C目录]:表示转到指定目录下去执行jar命令的操作。它相当于先使用cd命令转该目录下再执行不带-C参数的jar命令,它只能在创建和更新JAR文件包的时候可用。

● 文件名:指定一个文件/目录列表,这些文件/目录就是要添加到JAR文件包中的文件/目录。如果指定了目录,那么使用jar命令打包的时候会自动把该目录中的所有文件和子目录打入包中。

下面举一些例子来说明jar命令的用法。

例1:jar cf HelloWorld.jar mypackage

该命令将包mypackage中的文件打包,没有执行过程的显示,执行结果是在当前目录生成了HelloWorld.jar文件。如果当前目录已经存在HelloWorld.jar,那么该文件将被覆盖,如图1-23所示。

图1-23 例1

例2:jar cvf HelloWorld.jar mypackage

该命令与上例中的结果相同,但是由于v参数的作用,显示出了打包过程,如图1-24所示。

图1-24 例2

例3:jar cvfM HelloWorld.jar mypackage

该命令与例2结果类似,但在生成的HelloWorld.jar中没有包含META-INF/MANIFEST文件,打包过程的信息也略有差别,如图1-25所示。

图1-25 例3

例4:jar cvfm HelloWorld.jar manifest.mf mypackage

运行结果与例2相似,显示信息也相同,只是生成JAR包中的META-INF/MANIFEST内容不同,包含了manifest.mf的内容,如图1-26所示。

图1-26 例4

其中,manifest.mf的内容如下:

            Main-Class: mypackage.HelloWorld
            //注意:最后一行要有一个空行

例5:jar tf HelloWorld.jar

在HelloWorld.jar已经存在的情况下,可以查看HelloWorld.jar中的内容,如对于例4生成的HelloWorld.jar执行此命令,结果如图1-27所示。

图1-27 例5

例6:jar tvf HelloWorld.jar

除例5中显示的内容外,还可以显示包内文件的详细信息,如图1-28所示。

图1-28 例6

例7:jar xvf HelloWorld.jar

解开HelloWorld.jar到当前目录,不显示任何信息。如果要显示解压缩的详细信息,可以使用如下命令:

            jar  xvf  HelloWorld.jar

此时会显示如图1-29所示的信息。

图1-29 例7

1.3.5 生成API文档——javadoc命令

前文中我们已经讲到该如何充分利用Java的帮助文档,其中最重要的文档是Java的API文档。这些API文档是Sun开发的JDK核心Java类的API文档。

既然Sun能够为它的类生成API文档,那我们也可以为自己开发的类生成API文档。在稍微大型的项目中,生成API文档不仅有利于开发人员之间的沟通,还能够为项目留下一份参考的API,便于代码的维护和传播。

JDK为我们提供了一个命令用于生成API文档,即javadoc。javadoc解析Java源文件中的声明和文档注释,并产生相应的HTML默认页,描述公有类、保护类、内部类、接口、构造函数、方法和域。在实现时,javadoc要求且依赖于Java编译器完成其工作。javadoc调用部分javac编译声明部分,忽略成员实现。它建立类的内容,包括类层次和“使用”关系,然后从中生成HTML。javadoc还从源代码的文档注释中获得用户提供的文档。当javadoc建立其内部文档结构时,它将加载所有引用的类。由于这一点,javadoc必须能查找到所有引用的类,包括引导类、扩展类和用户类。

下面分两个方面来讲解javadoc命令的使用。

(1)javadoc命令的语法结构

javadoc的语法格式如下:

            javadoc [命令选项] [包名] [源文件名] [ @files ]

其中:

● [包名]为用空格分隔的一系列包的名字,包名不允许使用通配符,如“*”。

● [源文件名]为用空格分隔的一系列的源文件名,源文件名可包括路径和通配符,如“*”。

● [ @files ]是以任何次序包含包名和源文件的一个或多个文件。

(2)命令选项

javadoc命令选项包括如下几种可选属性。

● -overview <文件>:读取HTML文件的概述文档。

● -public:仅显示公共类和成员。

● -protected:显示受保护/公共类和成员(默认)。

● -package:显示软件包/受保护/公共类和成员。

● -private:显示所有类和成员。

● -help:显示命令行选项并退出。

● -doclet <类>:通过替代doclet生成输出。

● -docletpath <路径>:指定查找doclet类文件的位置。

● -sourcepath <路径列表>:指定查找源文件的位置。

● -classpath <路径列表>:指定查找用户类文件的位置。

● -exclude <软件包列表>:指定要排除的软件包的列表。

● -subpackages <子软件包列表>:指定要递归装入的子软件包。

● -breakiterator:使用BreakIterator计算第1句。

● -bootclasspath:<路径列表> 覆盖引导类加载器所装入的类文件的位置。

● -source <版本>:提供与指定版本的源兼容性。

● -extdirs <目录列表>:覆盖安装的扩展目录的位置。

● -verbose:输出有关Javadoc正在执行的操作的消息。

● -locale <名称>:要使用的语言环境,例如en_US或en_US_WIN。

● -encoding <名称>:源文件编码名称。

● -quiet:不显示状态消息。

● -J<标志>:直接将 <标志> 传递给运行时系统。

例如,我们来为HelloWorld.java生成API文档,执行如下命令:

            javacdoc mypackage\*.jara -d javadoc

该命令用于为mypackage包下的类生成API,输出目录为javadoc。执行该命令后会输出一系列的执行记录,如图1-30所示。

图1-30 生成API文档

此时在D:\demo下就会产生一个目录javadoc,即为刚生成的API文档目录。查看D:\demo\javadoc目录,会显示固定文件名称(主要是API的框架文件,如首页面index.html)的文件目录,如图1-31所示。

图1-31 API生成目录

查看该API文档的方法是,双击“index.html”文件,即可弹出如图1-32所示的API页面。

图1-32 查看API文档

通过与1.2.4节的图1-19对比可知,我们创建的API文档与Sun的API文档结构完全相同,这就是javadoc的作用,它统一了生成API的模板。如果你创建了很多Java类,那么就可以发挥实际的方便作用了。

1.4 本课小结

到这里我们就完成了本课内容的讲解,我们将本课的实例代码打包为HelloWorld.zip,其包含的目录和文件如下:

                HelloWorld.zip
                ├—HelloWorld.jar                       生成的JAR包
                ├—manifest.mf                          生成JAR包时的manifest文件
                |
                ├—javadoc                              生成的Java API文档
                |  |  allclasses-frame.html
                |  |  allclasses-noframe.html
                |  |  constant-values.html
                |  |  deprecated-list.html
                |  |  help-doc.html
                |  |  index-all.html
                |  |  index.html
                |  |  overview-tree.html
                |  |  package-list
                |  |  stylesheet.css
                |  |
                |  ├—mypackage
                |  |      HelloWorld.html
                |  |      package-frame.html
                |  |      package-summary.html
                |  |      package-tree.html
                |  |
                |  └—resources
                |         inherit.gif
                |
                └—mypackage                            java和class包目录
                      HelloWorld.class                   class文件
                      HelloWorld.java                    java源文件

该文件放在光盘中\source目录下,读者可以查阅该代码。

1.4.1 总结本课的知识点

本节课首先讲解了Java语言的市场地位,然后分3个大节逐层深入进行讲解,并将理论与实践相结合。每一个大节分多个小节,每一个小节都对应了一个知识点,共包含13个知识点,如表1-3所示。

表1-3 本课知识点列表

培训讲师可以参照表中最后一列的参考时间控制讲解进度,即75分钟讲完本课内容。参加培训的学生在听完讲课后,最好再回顾一遍。对于自学者来说,相对要花费差不多2倍的时间来学习这些知识点。

对于本章知识点的学习,除了要学习理论知识点以外,还应该注重实践操作。下面的两个小节分别从理论和实践两个方面来为你提出学习的要求。

1.4.2 要掌握的关键点

对于本节课的内容,我们应该掌握如下的关键点。

● Java语言排名第一,且市场占有率超过了1/5。

● Java语言的定义为:Java是一种简单的(Simple)、面象对象的(Object-Oriented)、分布式的(Distributed)、解释的(Interpreted)、健壮的(Robust)、安全的(Secure)、结构中立的(Architecture-neutral)、可移植的(Portable)、高性能的(High-Performance)、多线程的(Multi-Threaded)、动态的(Dynamic)语言

● Java语言的构成为JIT、JVM、JRE、JDK,其中JIT用来执行即时编译,JVM是Java虚拟机,JRE是Java运行时环境,JDK是Java开发工具包

● Java的开发环境应该包括JDK和JRE,需要设置如下两个环境变量:

                $JAVA_HOME=C:\j2sdk1.6.0;
                $PATH=C:\j2sdk1.6.0\bin;

● Java API文档是Java程序员的必备手册

● 一个简单的Java类包括:包名、类名、变量、函数、入口函数

● 关于HelloWorld.java的4种执行命令。

编译:javac mypackage\HelloWorld.java

运行:java mypackage.HelloWorld

打包:jar cvfm HelloWorld.jar manifest.mf mypackage

生成API:javadoc mypackage\*.java -d javadoc

Tips

这些知识点是本节课的精华语录,不仅要记住,还应该转化为自己的东西。

1.4.3 课后上机作业

本节课是Java语言的第一课,重在讲解Java语言的入门知识,Java开发环境的搭建,以及Java类的开发。下面我们根据本节的知识点,来布置上机作业任务,共3道题(150分钟)。

1.安装和配置Java开发环境(时间:60分钟)

在http://java.sun.com/javase/downloads/index.jsp上下载JDK 6的安装包软件,然后执行安装过程。要求:

● 将JDK安装到D:盘下。

● 将JRE安装到默认目录C:\Program Files\Java下。

● 设置如下两个环境变量。

                $JAVA_HOME=C:\j2sdk1.6.0;
                $PATH=C:\j2sdk1.6.0\bin;

● 在命令行分别执行如下命令,查看配置情况。

                javac -version
                java -version
                javac -help

2.学会查找Java API文档(时间:30分钟)

在中文API地址http://gceclub.sun.com.cn/Java_Docs/jdk6/html/zh_CN/api/index.html上查找一个类java.lang.String,显示的界面将会如图1-33所示。

图1-33 查找java.lang.String的API界面

3.开发第一个Java程序(时间:60分钟)

开发一个以你的名字命名的类,例如Liuzhongbing,包名为mypackage。该类的作用是往控制台输出一个字符串“Hello Liuzhongbing!”。例如下例所示:

                package mypackage;

                /**
                * @author liuzhongbing lzb_box@163.com
                */
                public class Liuzhongbing {

                    /**
                    * 变量
                    */
                    private String name = "Liuzhongbing";

                    /**
                    * 函数
                    */
                    public void say() {
                      System.out.println("Hello " + name + "!");
                    }

                    /**
                    * 执行入口函数
                    * @param args
                    */
                    public static void main(String args[]) {
                      //创建类的实例
                      Liuzhongbing inst = new Liuzhongbing();

                      //调用函数
                      inst.say();
                    }
                }

然后分别执行如下的4个命令来操作该类。

(1)编译:javac mypackage\Liuzhongbing.java。

此时,将会在mypackage目录下产生一个以你的名字命名的class文件,如Liuzhongbing.class。

(2)运行:java mypackage.Liuzhongbing。

此时,将会在控制台输出一个包含你名字的字符串,例如“Hello Liuzhongbing!”。

(3)打包:jar cvfm Liuzhongbing.jar manifest.mf mypackage。

Tips

manifest.mf中的主类名应该改为你新建的类名,如mypackage.Liuzhongbing。

(4)生成API:javadoc mypackage\*.java -d javadoc。

此时,打开javadoc下的index.html文件,将会在类列表中看到以你的名字命名的类,如图1-34所示。

图1-34 你生成的API的样子

1.4.4 继续下一课:JVM内存结构及其调优

回顾一下本节课的内容,共讲解了13个知识点,并总结了7个关键点要求掌握,最后给出了3个上机任务,旨在让读者能够搭建起Java的开发环境,会利用Java API文档来查找类,并学会普通Java类的开发、编译、运行、打包和生成API的方法。掌握了这里所提及的内容,即标志着你真正迈入Java的门槛了。

本节课使用命令行来编译和运行类的方式是最原始的方式,但也是最基础的方式,其他的一切高级方式都是以命令行为基础的。一旦你掌握了命令行的方法,就可以过渡到高级开发工具来进行Java开发了。下一课我们将深入到JVM内部,讲解JVM的内存结构,并进一步实战JVM性能调优。