标识符是赋给类、方法或是变量的名字。一个标识符可以是大写和小写字母、数字、
下划线、美元符号的任意顺序组合,但不能以一个数字开始。否则容易与数字、常量相混
淆。再次强调一下,Java是区分大小写的,VALUE和Value是两个不同的标识符。下面是一
些有效的标识符:
AvgTemp count a4 $test this_is_ok
下面是一些无效的变量名:
2count high-temp Not/ok
常量(literal)
在Java中,常量用literal表示。例如,下面是一些常量:
100 98.6 'X' "This is a test"
从左到右,第一个表示一个整数,第二个是浮点值,第三个是一个字符常数,最后是
一个字符串。常量能在任何地方被它所允许的类型使用,代表的是所属类型的一个值。
Java定义了3种注释的类型。其中2种注释类型你已经知道了:单行注释和多行注释。
第3种注释类型被称为文档注释(documentation comment)。这类注释以HTML文件的形式
为你的程序作注释。文档注释以“/**”开始,以“*/”结束
Java定义了8个简单(或基本)的数据类型:字节型(byte),短整型(short),整型
(int),长整型(long),字符型(char),浮点型(float),双精度型(double),布尔
型(boolean),这些类型可分为4组:
· 整数:该组包括字节型(byte),短整型(short),整型(int),长整型(long),
它们有符号整数。
· 浮点型数:该组包括浮点型(float),双精度型(double),它们代表有小数精度
要求的数字。
· 字符:这个组包括字符型(char),它代表字符集的符号,例如字母和数字。
· 布尔型:这个组包括布尔型(boolean),它是一种特殊的类型,表示真/假值。
表 3-1 整数的各种类型及特性
名称 长度 数的范围
长整型 64 –9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
整型 32 –2,147,483,648 ~ 2,147,483,647
短整型 16 –32,768 ~ 32,767
字节型 8 –128~127
当你从网络或文件处理数据流的时候,字节类型的变量特别有用。当你处理可能与Java的其他内置
类型不直接兼容的未加工的二进制的数据时,它们也是有用的。通过“byte”这个关键字的使用来定义字节变量。
例如,下面定义了2个变量,称为b
和c:byte b,c;
int类型的变量通常被用来控制循环及作数组的下标,似乎使用字节型和短整型可以节约空间,但是不能保证 Java 不会内部把
那些类型提升到整型。记住,类型决定行为,而不是大小(惟一的例外是数组,字节型的
数据保证每个数组元素只占用一个字节,短整型使用 2 个字节,整型将使用4个
long长整型数的范围是相当大的。这使得大的、整个数字都被需要时,它是非常有用的
有2种浮点型,单精度浮点型(float)及双精度(double)浮点型。
当表示美元和分时,单精度浮点型是有用的;当你需要保持多次反复迭代
的计算的精确性时,或在操作值很大的数字时,双精度型是最好的选择。
表 3-2 浮点型分类及其特性
名称 位数 数的范围
DOUBLE 64 1.7E–308~1.7E+308
float 32 3.4E–038~3.4E+038
Java中的char 类型是16位,其范围是0~
65,536,没有负数的char
标准字符集ASCII 码的范围仍然是0~127,扩展的8
位字符集ISO-Latin-1的范围是0~255,ASCII字符集占用了Unicode字符集的前127个值
48<-> 0 65<->A 97<->a
十六进制数的范围是0~15,这样用
A~ F(或a~f)来替代10~15
表 3-3 字符转义序列
转义序列 说明
\ddd 八进制字符(ddd)
\uxxxx 十六进制Unicode码字符
\' 单引号
\" 双引号
\\ 反斜杠
\r 回车键
\n 换行
\f 换页
\t 水平制表符
\b 退格
类型转换
class Conversion {
public static void main(String args[]) {
byte b;
int i = 257;
double d = 323.142;
System.out.println("\nConversion of int to byte.");
b = (byte) i;
System.out.println("i and b " + i + " " + b);
System.out.println("\nConversion of double to int.");
i = (int) d;
System.out.println("d and i " + d + " " + i);
System.out.println("\nConversion of double to byte.");
b = (byte) d;
System.out.println("d and b " + d + " " + b);
}
}
该程序的输出如下:
Conversion of int to byte.
i and b 257 1
Conversion of double to int.
d and i 323.142 323
Conversion of double to byte.
d and b 323.142 67
byte a = 40;
byte b = 50;
byte c = 100;
b = (byte)(b * 2);
数组(array)是相同类型变量的集合,可以使用共同的名字引用它。数组可被定义为
任何类型,可以是一维或多维。数组中的一个特别要素是通过下标来访问它。数组提供了
一种将有联系的信息分组的便利方法。
定义了数据类型为int,名为month_days的数组:int month_days[];
分配了一个12个整型元素的数组并把它们和数组month_days 链接起来:month_days = new int[12];
将值28赋给数组month_days 的第二个元素:month_days[1] = 28;
序显示存储在下标为3的数组元素中的值
System.out.println ( month_days [ 3 ]);
将对数组变量的声明和对数组本身的分配结合起来是可以的,如下所示:
int month_days[] = new int[12];
定义了一个初始化的整数数组
int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31 };
定义了一个名为twoD的二维数组变量。一个4行5列的数组
int twoD[][] = new int[4][5];
class TwoDArray {
public static void main(String args[]) {
int twoD[][]= new int[4][5];
int i, j, k = 0;
for(i=0; i<4; i++)
for(j=0; j<5; j++) {
twoD[i][j] = k;
k++;
}
for(i=0; i<4; i++) {
for(j=0; j<5; j++)
System.out.print(twoD[i][j] + " ");
System.out.println();
}
}
}
程序运行的结果如下:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
另一种多维数组定义
int twoD[][] = new int[4][];
twoD[0] = new int[5];
twoD[1] = new int[5];
twoD[2] = new int[5];
twoD[3] = new int[5];
class TwoDAgain {
public static void main(String args[]) {
int twoD[][] = new int[4][];
twoD[0] = new int[1];
twoD[1] = new int[2];
twoD[2] = new int[3];
twoD[3] = new int[4];
int i, j, k = 0;
for(i=0; i<4; i++)
for(j=0; j twoD[i][j] = k;
k++;
}
for(i=0; i<4; i++) {
for(j=0; j System.out.print(twoD[i][j] + " ");
System.out.println();
}
}
}
该程序产生的输出如下:
0
1 2
3 4 5
6 7 8 9
[0][0]
[1][0] [1][1]
[2][0] [2][1] [2][2]
[3][0] [3][1] [3][2] [3][3]
声明数组还有第二种格式:
type[ ] var-name;
这里,方括号紧跟在类型标识符type的后面,而不是跟在数组变量名的后面。例如,
下面的两个定义是等价的:
int al[] = new int[3];
int[] a2 = new int[3];
下面的两个定义也是等价的:
char twod1[][] = new char[3][4];
char[][] twod2 = new char[3][4];
关于break,在这里要记住两点。首先,一个循环中可以有一个以上的break语句。但要
小心,太多的break语句会破坏你的代码结构。其次,switch语句中的break仅仅影响该switch
语句,而不会影响其中的任何循环。
可以使用break语句直接强行退出循环,忽略循环体中的任何其他语句和循环的条件测
试。在循环中遇到break语句时,循环被终止,程序控制在循环后面的语句重新开始。下面
是一个简单的例子:
// Using break to exit a loop.
class BreakLoop {
public static void main(String args[]) {
for(int i=0; i<100; i++) {
if(i == 10) break; // terminate loop if i is 10
System.out.println("i: " + i);
}
System.out.println("Loop complete.");
}
}
该程序产生如下的输出:
i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
Loop complete.
正如你看到的那样,尽管for循环被设计为从 0执行到99,但是当i等于10时,break语
句终止了程序。
break语句能用于任何 Java循环中,包括人们有意设置的无限循环。例如,将上一个程
序用while循环改写如下。该程序的输出和刚才看到的输出一样。
// Using break to exit a while loop.
class BreakLoop2 {
public static void main(String args[]) {
int i = 0;
while(i < 100) {
if(i == 10) break; // terminate loop if i is 10
System.out.println("i: " + i);
}
System.out.println("Loop complete.");
}
}
该程序产生如下的输出:
i: 0
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
Loop complete.
正如你看到的那样,尽管for循环被设计为从 0执行到99,但是当i等于10时,break语
句终止了程序。
break语句能用于任何 Java循环中,包括人们有意设置的无限循环。例如,将上一个程
序用while循环改写如下。该程序的输出和刚才看到的输出一样。
// Using break to exit a while loop.
class BreakLoop2 {
public static void main(String args[]) {
int i = 0;
while(i < 100) {
if(i == 10) break; // terminate loop if i is 10
System.out.println("i: " + i);
i++;
}
第5 章程序控制语句 85
System.out.println("Loop
System.out.println("Loop complete.");
}
}
在一系列嵌套循环中使用break语句时,它将仅仅终止最里面的循环。例如:
// Using break with nested loops.
class BreakLoop3 {
public static void main(String args[]) {
for(int i=0; i<3; i++) {
System.out.print("Pass " + i + ": ");
for(int j=0; j<100; j++) {
if(j == 10) break; // terminate loop if j is 10
System.out.print(j + " ");
}
System.out.println();
}
System.out.println("Loops complete.");
}
}
该程序产生如下的输出:
Pass 0: 0 1 2 3 4 5 6 7 8 9
Pass 1: 0 1 2 3 4 5 6 7 8 9
Pass 2: 0 1 2 3 4 5 6 7 8 9
Loops complete.
标签break语句的通用格式如下所示:
break label;
要指定一个代码块,在其开头加一个标签即可。标签(label)可以是任何合法有效的
Java标识符后跟一个冒号。一旦你给一个块加上标签后,你就可以使用这个标签作为break
语句的对象了。这样做会使执行在加标签的块的结尾重新开始。例如,下面的程序示例了 3
个嵌套块,每一个都有它自己的标签。break语句使执行向前跳,调过了定义为标签second
的代码块结尾,跳过了2个 println ( )语句。
// Using break as a civilized form of goto.
class Break {
public static void main(String args[]) {
boolean t = true;
first: {
second: {
third: {
System.out.println("Before the break.");
if(t) break second; // break out of second block
System.out.println("This won't execute");
}
System.out.println("This won't execute");
}
System.out.println("This is after second block.");
}
}
}
运行该程序,产生如下的输出:
Before the break.
This is after second block.
标签break语句的一个最普遍的用法是退出循环嵌套。例如,下面的程序中,外层的循
环只执行了一次:
// Using break to exit from nested loops
class BreakLoop4 {
public static void main(String args[]) {
outer: for(int i=0; i<3; i++) {
System.out.print("Pass " + i + ": ");
for(int j=0; j<100; j++) {
if(j == 10) break outer; // exit both loops
System.out.print(j + " ");
}
System.out.println("This will not print");
}
System.out.println("Loops complete.");
}
}
该程序产生如下的输出:
Pass 0: 0 1 2 3 4 5 6 7 8 9 Loops complete.
你可以看到,当内部循环退到外部循环时,两个循环都被终止了。
记住如果一个标签不在包围break的块中定义,你就不能break到该标签。例如,下面的
程序就是非法的,且不会被编译:
// This program contains an error.
class BreakErr {
public static void main(String args[]) {
one: for(int i=0; i<3; i++) {
System.out.print("Pass " + i + ": ");
}
for(int j=0; j<100; j++) {
if(j == 10) break one; // WRONG
System.out.print(j + " ");
}
}
}
因为标签为one的循环没有包围break语句,所以不能将控制传递到该块。
在while和do while循环中,continue语句使控制直接转移
给控制循环的条件表达式,然后继续循环过程。在for循环中,循环的反复表达式被求值,
然后执行条件表达式,循环继续执行。对于这3种循环,任何中间的代码将被旁路。
下例使用continue语句,使每行打印2个数字:
// Demonstrate continue.
class Continue {
public static void main(String args[]) {
for(int i=0; i<10; i++) {
System.out.print(i + " ");
if (i%2 == 0) continue;
System.out.println("");
}
}
}
该程序使用%(模)运算符来检验变量i是否为偶数,如果是,循环继续执行而不输出
一个新行。该程序的结果如下:
0 1
2 3
4 5
6 7
8 9
对于break语句,continue可以指定一个标签来说明继续哪个包围的循环。下面的例子
运用continue语句来打印0到9的三角形乘法表:
// Using continue with a label.
class ContinueLabel {
public static void main(String args[]) {
outer: for (int i=0; i<10; i++) {
for(int j=0; j<10; j++) {
if(j > i) {
System.out.println();
continue outer;
}
System.out.print(" " + (i * j));
}
}
System.out.println();
}
}
在本例中的continue语句终止了计数j的循环而继续计数i的下一次循环反复。该程序的
输出如下:
0
0 1
0 2 4
0 3 6 9
0 4 8 12 16
0 5 10 15 20 25
0 6 12 18 24 30 36
0 7 14 21 28 35 42 49
0 8 16 24 32 40 48 56 64
0 9 18 27 36 45 54 63 72 81
很好的利用continue语句的情况很少,一个原因是Java提供了一系列丰富的循环语句,
可以适用于绝大多数应用程序。但是,对于那些需要提早反复的特殊情形,continue语句提
供了一个结构化的方法来实现。
最后一个控制语句是return。return语句用来明确地从一个方法返回。也就是,return语
句使程序控制返回到调用它的方法。因此,将它分类为跳转语句。尽管对return语句的详细
讨论在第 7 章开始,这里对其作简要地介绍。
在一个方法的任何时间,return语句可被用来使正在执行的分支程序返回到调用它的方
法。下面的例子说明这一点。下例中,由于是Java 运行系统调用main(),因此,return语句
使程序执行返回到Java运行系统。
// Demonstrate return.
class Return {
public static void main(String args[]) {
boolean t = true;
System.out.println("Before the return.");
if(t) return; // return to caller
System.out.println("This won't execute.");
}
}
该程序的结果如下:
Before the return.
正如你看到的一样,最后的println( )语句没有被执行。一旦return语句被执行,程序控
制传递到它的调用者。
最后一点:在上面的程序中,if(t)语句是必要的。没有它,Java编译器将标记“执行不
到的代码”(unreachable code)错误,因为编译器知道最后的println()语句将永远不会被
执行。为阻止这个错误,为了这个例子能够执行,在这里使用if语句来“蒙骗”编译器。