从本章开始,就要正式学习Java语言的程序设计,除了认识程序的架构外,本章还介绍了修饰符、关键字、一些基本的数据类型、变量、常量、运算符、表达式和流程控制语句。通过简单的范例,让大家能够对Java的语法以及编程代码规范有一定的了解。

 

2.1 java源文件组成元素

 

Java源文件可包含三个“顶级”要素:

 

  (1)一个包(package)声明(可选)

 

2)任意数量的导入(import)语句

 

3)类(class)声明

  

java 源文件 组织 组成java源文件的基本元素_Java

 

包的声明:

  多数软件系统是庞大的。为了方便管理,通常要将类组织成包。在包中可以存放类,也可以存放子包,从而形成具有层次结构的包。包可以根据需要任意组织,通常,要按照类的用途、含义来组织包。

技术提供了包的机制,以此来组织相关的类。声明包的句法如下:

    package <top_pkg_name> [.<sub_pkg_name>];

package命令指明源文件中的类属于某个特定的包。例如:

    package com.itjob.java;

com.itjob.java,则最终生成的*.class文件应该在$path\com\itjob\java目录中。

包的引入:

import命令告诉编译器类在哪里。import命令的语法:

    import  包名称.子包名称.类名称; //手工导入所需要的类

    import  包名称.子包名称.*;à //由 JVM自动加载所需要的类

  例如:

    import com.itJob.*;

    import java.util.List;

    import java.io.*;

包的静态引入:

 

  静态导入为Java的新特性,在JDK1.5之后提供了静态导入功能。如果一个类中的方法全部是使用static声明的静态方法,则在导入的时候就可以直接使用“import static”的方式导入,导入的格式如下:import static包.类.*;

如果按照非静态的import导入的话,则调用的时候肯定使用的是:类.方法()。而使用了静态导入“import static包.类.*;”的语句,则在主方法中直接使用该类中的方法即可。

例如TestJava2_1:

 

//Operate.java
package com.itjob.java;

public class Operate
{              //  里面的方法全部都是 static类型
    public static int add(int i, int j)
    {    //  加法操作
        return i + j;
    }

    public static int sub(int i, int j)
    {    //  减法操作
        return i - j;
    }

    public static int mul(int i, int j)
    {    //  乘法操作
        return i * j;
    }

    public static int div(int i, int j)
    {    //  除法操作
        return i / j;
    }
}

 

//MathApp.java
package com.itjob.test;

import static com.itjob.java.Operate.*;
import static com.qiyu.util.Arith.add;

public class MathApp
{
    public static void main(String[] args)
    {
        System.out.println(add(23, 34));
    }
}

 

 

编译JAVA带包名的源代码编译:

javac -d Operate.java

javac -d MathApp.java

执行带包名的JAVA应用程序:

java com.itjob.test.MathApp  或:java -classpath com.itjob.test.MathApp

类声明:

需要注意的是,如果将一个类声明成public,则也要将文件名称取成和这个类一样的名称。也就是说,在一个Java文件里,最多只能有一个public类,否则java的文件便无法命名,但是可以有多个非public类。

Jar包:

  如果在工作过程中,不想让用户看到我们自己实现的类的具体内容,类似于C和C++中的库文件一样,我们可以利用jar命令来进行封装。JAR是一种与平台无关的文档格式,全称为Java Archive,翻译成中文叫Java归档,它相当于一种压缩格式,可以把众多的文件(Java Applet及Application的类文件、图像或声音等格式)合成一个文件,就像ZIP和RAR。

JAR文件好处:

安全:能够对JAR文件进行数字签名,只让能够识别数字签名的用户使用里面的东西。

压缩:加快读取速度。文件变小,JAR的压缩机制跟ZIP完全相同

包封装:能够让JAR包里面的文件依赖于同一版本的类文件

可移植性:JAR包作为内嵌在java平台内部处理的标准,能够在各种平台上直接使用。

jdk提供了jar的工具,就在java安装目录的bin目录下有一个jar.exe的应用程序,可以使用此工具打包。

用法:jar {ctxu}[vfm0M] [jar-文件] [manifest-文件] [-C 目录] 文件名 ...

-c创建新的归档

-t列出归档内容的列表

-x展开归档中的命名的(或所有的〕文件

-u更新已存在的归档

-v生成详细输出到标准输出上

-f指定归档文件名

-m包含来自指定的清单(manifest〕文件的清单(manifest〕信息

-0只存储方式;未用ZIP压缩格式

-M不产生所有项的清单(manifest〕文件

-I为指定的jar文件产生索引信息

-C更改为指定的目录并包含其中的文件

实例:

1:将两个class文件归档到一个名为classes.jar的归档文件中

jar  cvf  classes.jar  one.class   two.class

2:把test目录生成test.jar文件

jar  cvf  test.jar  test

3:将当前目录下的所有的*.class与*.gif文件打包到一个JAR文件中

jar  cf  classes.jar  *.class  *.gif

4:显示出jar文件中包的所有目录和文件名列表

jar  tvf  test.jar

5:解压jar文件

jar  xvf  test.jar

6:将某个文件加入到某个*.jar文件中

jar  uvf  classes.jar  otherFile.class

  除了可以利用jar命令来产生jar包以外,还可以利用MyEclipse的相关工具,使用说明如下:在左边的Package属性页右键包名或*.java,然后选择“Export…”,在弹出的Export对话框中选择Java子目录下的“JAR file”,然后点击“Next”,在弹出的Jar Export对话框中点击“Browse…”,选择你要保存的路径和jar包名称即可。

引入jar包:

  有了jar包之后,该如何引入呢?

对于命令行而言,假设生成的jar包在C盘:

编译:javac -classpath .;c:\myfunc.jar TestJar.java

//或javac -classpath c:\myfunc.jar TestJar.java

运行:java -classpath .;c:\myfunc.jar TestJar

//对于运行时利用-classpath指明路径的时候,当前的.不能少

利用MyEclipse,在左侧的Package属性页上右键项目工程文件,选择“Properties”或按快捷键“Alt+Enter”,在弹出的“Properties for …”对话框中选择“Java Build Path”,然后在右边选择“Libraries”属性页,点击“Add External JARs…”,在弹出的对话框中选择你的jar包即可。引入jar包之后,使用jar包里面的类和使用普通的类似。

Java类库和包:

  类库是描述提供某种功能的模块的一般术语。类库被组织成许多包,每个包都包含若干个类。 Java类库中几个重要的包:java.lang、java.awt、java.applet、java.net、java.io、java.util。

Java中常见的包说明如图2-1所示:

java 源文件 组织 组成java源文件的基本元素_Java_02

 

图2-1  Java常见包

2.2 Java 基本语法

本节将仔细探讨Java语言的一些基本规则及用法。

2.2.1 类(class)

Java程序是由类(class)所组成,至于类的概念在以后会有详细讲解,现在只要先记住所有的Java程序都是由类组成的就可以了。下面的程序片段即为定义类的典型范例:

public class Test  // 定义public类Test

{

//…

}

上面的程序定义了一个新的public类Test,这个类的原始程序的文件名称应取名为Test.java。类Test的范围由一对大括号所包含。public是Java的关键字,指的是对于类的访问方式为公有。

需要注意的是,由于Java程序是由类所组成,因此在完整的Java程序里,至少需要有一个类。此外,本书曾在前面提到过在Java程序中,其原始程序的文件名不能随意命名,必须和public类名称一样,因此在一个独立的原始程序里,最多只能有一个public类,却可以有许多non-public类。当然,没有public类也是可以的。

2.2.2 大括号、段及主体

将类名称定出之后,就可以开始编写类的内容。左大括号“{”为类的主体开始标记,而整个类的主体至右大括号“}”结束。每个命令语句结束时,必须以分号“;”做结尾。当某个命令的语句不只一行时,必须以一对大括号“{}”将这些语句包括起来,形成一个程序段(segment)或是块(block)。

再以一个简单的程序为例来说明什么是段与主体。若是暂时看不懂TestJava2_2 这个程序,也不用担心,慢慢的都会讲到该程序中所用到的语句。在下面的程序中,可以看到main() method的主体以左右大括号包围起来;for循环中的语句不只一行,所以使用左右大括号将属于for循环的段内容包围起来;整个程序语句的内容又被第3与第13行的左右大括号包围,这个块属于public类TestJava2_2所有。此外,应该注意到每个语句结束时,都是以分号作为结尾。

范例:TestJava2_2.java 

java 源文件 组织 组成java源文件的基本元素_java 源文件 组织_03

 

2.2.3 程序运行的起始点 —— main() method

Java程序是由一个或多个类组合而成,程序起始的主体也是被包含在类之中。这个起始的地方称为main(),用左右大括号将属于main()段内容包围起来,称之为method(方法)。

main()方法为程序的主方法,在一个Java程序中有且只能有一个main()方法,它是程序运行的开端,通常看到的main() method如下面的语句片段所示:

public static void main(String args[])   // main() method,主程序开始

{

//…

}

如前一节所述,main() method之前必须加上public static void 这三个标识符。public代表main()公有的method;static表示main()在没有创建类对象的情况下,仍然可以被运行;void则表示main()方法没有返回值。main后的括号()中的参数String args[]表示运行该程序时所需要的参数,这是固定的用法,如果现在不了解也没有关系,在以后的章节中会一一介绍。

2.2.4 Java 程序的注释

为程序添加注释可以用来解释程序的某些语句的作用和功能,提高程序的可读性。也可以使用注释在原程序中插入设计者的个人信息。此外,还可以用程序注释来暂时屏蔽某些程序语句,让编译器暂时不要处理这部分语句,等到需要处理的时候,只需把注释标记取消就可以了,Java里的注释根据不同的用途分为三种类型:

·单行注释

·多行注释

·文档注释

单行注释:就是在注释内容前面加双斜线(//),Java编译器会忽略掉这部分信息。多用于对属性和变量的提示信息。如下所示:

int num;//定义一个整数

多行注释:就是在注释内容前面以单斜线加一个星形标记(/*)开头,并在注释内容末尾以一个星形标记加单斜线(*/)结束。当注释内容超过一行时一般使用这种方法,一般在源文件最开头,对整个源文件的详细说明或多行代码的注释。如下所示:

/*

* int c = 10;

* int x = 5;

*/

通常在一个源文件的开头利用多行注释对整个文件做一些说明,包括文件的名字、功能、作者、创建日期等等相关信息。

文档注释:是以单斜线加两个星形标记(/**)开头,并以一个星形标记加单斜线(*/)结束。用这种方法注释的内容会被解释成程序的正式文档,并能包含进如javadoc之类的工具生成的文档里,用以说明该程序的层次结构及其方法。后面会详细介绍。

请参阅《Java整个源文件的组织管理情况.txt》。

2.2.5 Java 中的标识符

Java中的包、类、方法、参数和变量的名字,可由任意顺序的大小写字母、数字、下划线(_)和美元符号($)组成,但标识符不能以数字开头,不能是Java中的保留关键字。标识符是严格区分大小写的。

·下面是合法的标识符:

yourname

your_name

_yourname

$yourname

·下面是非法的标识符:

class//跟关键字同名

67.9//数字开图

Hello Careers//包含空格

小提示:

刚接触编程语言,可能会觉得记住上面的规则很麻烦,所以标识符最好永远用字母开头,而且尽量不要包含其他的符号。当然还要尽量做到顾名思义。

2.2.6 Java 的关键字

和其他语言一样,Java中也有许多保留关键字,如public、static等,这些保留关键字不能当作标识符使用。下面列出了Java中的保留关键字,这些关键字并不需要强记,因为一旦使用了这些关键字做标识符时,编辑器会自动提示错误。另外,Java关键字都是小写的。

Java中的保留关键字:

abstract、assert、boolean、break、byte、case、catch、char、class、continue、default、do、double、else、enum、extends、false、final、finally、float、for、if、implements、import、instanceof、int、interface、long、native、new、null、package、private、protected、public、return、short、static、super、switch、synchronized、this、throw、throws、transient、true、try、void、volatile、while

要特别注意的是,虽然goto、const在Java中并没有任何意义,却也是保留字,与其它的关键字一样,在程序里不能用来做为自定义的标识符。

2.2.7 Java 的数据类型

数据类型在程序语言的构成要素里,占有相当重要的地位。Java的数据类型可分为原始数据类型与引用数据类型。

原始数据类型也称为基本数据类型,它们包括了最基本的boolean、byte、char、short、int、long、float与double等类型。另一种数据类型为引用数据类型,它是以一种特殊的方式指向变量的实体,这种机制类似于C/C++的指针。这类的变量在声明时是不会分配内存的,必须另外进行开辟内存空间的操作,如字符串与数组均属于这种数据类型。

在这里只是先介绍基本数据类型,引用数据类型会在以后的章节中介绍。

在Java中规定了八种基本数据类型变量来存储整数、浮点数、字符和布尔值。如图2-2所示:

java 源文件 组织 组成java源文件的基本元素_jave基础_04

 

图2-2  Java的数据类型

2.2.7.1 基本数据类型

Java的基本数据类型如表2-1所示:

表2-1  Java的基本数据类型

java 源文件 组织 组成java源文件的基本元素_Java_05

 

2.2.7.1.1 整数类型

当数据不带有小数或分数时,即可以声明为整数变量,如3,-147等即为整数。Java中,整数数据类型可以分为long、int、short及byte四种,如表2-2所示:

表2-2  整数型

java 源文件 组织 组成java源文件的基本元素_jave基础_06

 

从上表可以看出,long为64位,也就是8个字节(bytes),可表示范围为-9223372036854775808到9223372036854775807;int为32 位,也就是4个字节,表示范围为-2147483648到2147483647;若是数据值的范围在-32768到32767之间时,可以声明为short(短整数)类型;若是数据值更小,在-128到127之间时,可以声明为byte类型以节省内存空间。

举例来说,想声明一个短整型变量sum时,可以在程序中做出如下的声明:

short sum;     //声明snum为短整型

经过声明之后,Java即会在可使用的内存空间中,寻找一个占有2个字节的块供sum变量使用,同时这个变量的范围只能在-32768到32767之间。

需要注意的是,Java把整数常量的数据类型均视为int型,因此,如果在程序中使用了超过2147483647这个大小的常量,编译时将发生错误,如下面的范例:

范例:TestJava2_3.java

//下面这段程序说明了值的可取范围的问题

public class TestJava2_3

{

    public static void main(String args[])

    {

        long num = 329852547553; // 声明长整型变量

        System.out.println("num = " + num);

    }

}

 

如果编译上面的程序代码,将会得到下列的错误信息:

TestJava2_3.java:5: integer number too large: 329852547553 

long num = 329852547553;

这是因为把整数常量看成是int类型,但329852547553这个整数已超出了int类型所能表示的范围,因此虽然把num的类型设为long,但编译时仍然会发生错误。要解决这个问题,只要在整数常量后面加上一个大写的“L”或小写的“l”即可,此举代表该常量是long类型的整数常量。所以只要把第6行的语句改成:

long num = 329852547553L;

即可成功地编译运行。

·数据类型的最大值与最小值

Java提供了long、int、short及byte四种整数类型的最大值、最小值的代码,以方便设计者使用。最大值的代码是MAX_VALUE,最小值是MIN_VALUE。如果要取用某个类型的最大值或最小值,只要在这些代码之前,加上它们所属的类的全名即可。举例来说,如果程序代码里需要用到长整数的最大值,如图2-3所示的语法表示。

java 源文件 组织 组成java源文件的基本元素_java 源文件 组织_07

 

图2-3  代码的表示法

由上面的语法可知,如果要使用某个类型的代码,则必须先指定该类型所在的类库以及该类型所属的类,但因java.lang这个类库属于常用类库,所以默认的Java程序会将它加载,因此在实际的应用上设计者可以将它省略。

Java所提供的整数的最大值与最小值的标识符及常量值,可在表2-3中查阅。若是不懂什么叫类库也没有关系,现在只要会使用它就行了,后面会讲。

表2-3 整数常量的最值

java 源文件 组织 组成java源文件的基本元素_Java_08

 

下面程序是输出Java定义的四种整数类型的常量的最大和最小值,可以将程序与上表做对照、比较。

范例:TestJava2_4.java 

 

//下面这段程序调用了表2-3中的方法,可以得到数据类型的最大值和最小值
public class TestJava2_4
{
    public static void main(String args[])
    {
        long long_max = java.lang.Long.MAX_VALUE;    //得到长整型的最大值
        int int_max = java.lang.Integer.MAX_VALUE;    //得到整型的最大值
        short short_max = Short.MAX_VALUE;        //得到短整型的最大值
        byte byte_max = Byte.MAX_VALUE;            //得到Byte型的最大值
        System.out.println("LONG的最大值:" + long_max);
        System.out.println("INT 的最大值:" + int_max);
        System.out.println("SHORT的最大值:" + short_max);
        System.out.println("BYTE的最大值:" + byte_max);
    }
}

 

 

输出结果:

LONG的最大值:9223372036854775807

INT 的最大值:2147483647

SHORT的最大值:32767

BYTE的最大值:127

程序TestJava2_4列出了各种整数类型的最大值,通过它的运行,可以了解到Java对于整数的最大值、最小值的规定。可以自己改写程序,输出一下最小值。

·溢出的发生

当整数的数据大小超出了可以表示的范围,而程序中又没有做数值范围的检查时,这个整型变量所输出的值将发生紊乱,且不是预期的运行结果。在下面的程序范例中,声明了一个整型的数,并把它赋值为整型所可以表示范围的最大值,然后将它分别加1及加2。

范例:TestJava2_5.java 

//整数值如果超出了自己所可以表示范围的最大值,会出现溢出

public class TestJava2_5

{

    public static void main(String args[])

    {

        int x = java.lang.Integer.MAX_VALUE;   // 得到整型的最大值

        System.out.println("x = " + x);

        System.out.println("x+1 = " + (x + 1));

        System.out.println("x+2 = " + (x + 2));

    }

}

 

输出结果:

x = 2147483647

x+1 = -2147483648

x+2 = -2147483647

当最大值加上1时,结果反而变成表示范围中最小的值;当最大值加上2时,结果变成表示范围中次小的值,这就是数据类型的溢出。这个情形会出现一个循环,若是想避免这种情况的发生,在程序中就必须加上数值范围的检查功能,或者使用较大的表示范围的数据类型,如长整型。

当声明了一整数i,其表示的范围为-2147483648 ~ 2147483647之间,当i的值设为最大值2147483647,仍在整数的范围内,但是当x加1或加2时,整数x的值反而变成-2147483648和-2147483647,成为可表示范围的最小及次小值。

上述的情形就像计数器的内容到最大值时会自动归零一样。而在整数中最小值为-2147483648,所以当整数x的值最大时,加上1就会变成最小值-2147483648,也就是产生了溢出。可以参考图3-3来了解数据类型的溢出问题。

java 源文件 组织 组成java源文件的基本元素_Java_09

 

图2-4  数据类型的溢出

为了避免int 类型的溢出,可以在该表达式中的任一常量后加上大写的“L”,或是在变量前面加上long,作为强制类型的转换。以TestJava2_6为例,在下面的程序中加上防止溢出的处理,为了方便比较,特地保留一个整数的溢出语句。

范例:TestJava2_6.java 

//下面的这段程序当整型发生溢出之后,用强制类型进行转换

public class TestJava2_6
{
    public static void main(String args[])
    {

        int x = java.lang.Integer.MAX_VALUE;

        System.out.println("x = " + x);

        System.out.println("x + 1 = " + (x + 1));

        System.out.println("x + 2 = " + (x + 2L));

        System.out.println("x + 3 = " + ((long) x + 3));
    }
}

 

输出结果:

x = 2147483647 

x + 1 = -2147483648 

x + 2 = 2147483649 

x + 3 = 2147483650 

程序说明:

1、第6行声明int类型的整数变量x,并赋值为整数最大值,即2147483647。

2、第7行输出x的值,即:2147483647。

3、第8行输出x+1的值,此时溢出发生,运行结果变成-2147483648。

4、第9行输出x+2的值,为了避免溢出发生,在表达式的常量部分2后加上L,执行结果变成2147483649。

5、第10行输出x+3的值,为了避免溢出发生,在表达式的整数部分x之前加上long,执行结果变成2147483650。

由上面的程序可知,处理int 类型的溢出,可以利用强制类型转换方式。但是对于long类型的溢出,就没有处理办法了,此时就需要在程序中加上变量值的界限检查,在运行时才不会发生错误。