语句
导航 语言基础 主题: ) |
现在我们已经将 Java 平台安装到了系统上,并且成功运行了第一个程序,接下来我们将了解程序是如何编写的。正如我们之前讨论的,程序是一组指令,即提供给计算机的任务。在 Java 中,这些指令被称为 **语句**。语句可以是单行代码,也可以是复杂的数学方程式。考虑以下代码行
代码节 3.1:简单的赋值语句。
int age = 24;
|
这行代码是一个简单的指令,它告诉系统初始化一个变量并将其值设置为 24。如果上述语句是程序中唯一的语句,它将类似于下面这样
代码列表 3.1:简单类中的语句。
public class MyProgram
{
public static void main(String[] args)
{
int age = 24;
}
}
|
Java 将其语句放在类声明中,在类声明中,语句通常放在方法声明中,如上所示。
最简单的语句是变量声明
代码节 3.2:简单的声明语句。
int age;
|
它定义了一个变量,该变量可以用来存储值以供以后使用。第一个标记是变量的 数据类型(该变量可以存储哪种类型的值)。第二个标记是变量的名称,您将通过它来引用该变量。然后每个声明语句都以分号 (;
) 结尾。
到目前为止,我们一直假设变量的创建是一个单独的语句。实质上,我们为这些变量分配一个值,这就是它的名称。当您在语句中为变量分配一个值时,该语句被称为 **赋值语句**(也称为 初始化语句)。您是否注意到还有一件事?是分号 (;
),它位于每个语句的末尾。明确表明一行代码是语句的标志是它以分号结尾。如果要编写多个语句,通常会将每个语句放在单独一行,并以分号结尾。考虑以下示例
代码节 3.3:多个赋值语句。
int a = 10;
int b = 20;
int c = 30;
|
您不必一定要使用新行来编写每个语句。就像英语一样,您可以从结束第一个语句的地方开始编写下一个语句,如下所示
代码节 3.4:同一行上的多个赋值语句。
int a = 10; int b = 20; int c = 30;
|
但是,将多个语句放在同一行中的唯一问题是,它非常难读。起初它看起来并不那么吓人,但一旦您拥有大量的代码,通常最好以一种有意义的方式来组织它。如果按照代码列表 3.4 中的写法,它看起来会更加复杂和难以理解。
现在我们已经了解了简单的赋值语句的结构,我们可以回顾一下我们所取得的成就。我们知道...
- 语句是编程中代码的单位。
- 如果我们要为变量分配一个值,则该语句被称为赋值语句。
- 赋值语句包括三个部分:数据类型、变量名(也称为标识符)和变量的值。我们将在后面的“变量”部分详细介绍标识符和值的性质。
现在,在我们继续下一个主题之前,您需要尝试理解以下代码的作用。
代码节 3.5:包含表达式的多个赋值语句。
int firstNumber = 10;
int secondNumber = 20;
int result = firstNumber + secondNumber;
System.out.println(result);
secondNumber = 30; // This won't change the value of secondNumber. See the note.
System.out.println(result); // Hence, the result will remain same.
|
前两个语句与 节 3.3 中的语句非常相似,但变量名不同。但是,第三个语句有点意思。我们已经谈到变量类似于礼品盒。将您的计算机内存想象成一个架子,您将所有这些盒子都放在上面。无论何时需要一个盒子(或变量),您都会调用它的标识符(即变量的名称)。因此,调用变量标识符 firstNumber
会得到数字 10
,调用 secondNumber
会得到 20
,因此,将两者相加,结果应该是 30
。这就是最后一个变量 result
的值。第三个语句中将数字相加的部分,即 firstNumber + secondNumber
,被称为 **表达式**,表达式决定了值的取值。如果它只是一个简单值,就像前两个语句中的那样,那么它被称为 **字面量**(值 **字面意思** 就是值,因此称为 **字面量**)。
请注意,在为 result
赋值后,如果我们为 firstNumber
或 secondNumber
分配不同的值,如第 5 行所示,它的值不会改变。
有了您刚刚获得的信息,您实际上可以编写一个可以将值加起来的不错的 Java 程序。
断言检查条件是否为真
代码节 3.6:返回语句。
public int getAge()
{
assert age >= 0;
return age;
}
|
每个 assert
语句都以分号 (;
) 结尾。但是,断言默认情况下是禁用的,因此您必须使用 -ea 参数运行程序才能启用断言 (java -ea [已编译程序的名称]
)。
语句按照其出现的顺序进行求值。执行流从最上面的语句开始,向下进行,直到遇到最后一个语句。语句可以被语句块替换。有一些特殊的语句可以根据条件重定向执行流,这些语句被称为 **分支** 语句,将在后面的部分详细介绍。
一组语句可以放在花括号中,作为单个块执行。这样的语句块可以命名,也可以为执行提供条件。以下是将一系列语句放在块中的方法。
代码节 3.7:语句块。
{
int a = 10;
int b = 20;
int result = a + b;
}
|
可以使用函数/方法调用、循环和迭代来影响程序流。在各种类型的分支结构中,我们可以轻松地挑选出两种通用的分支方法。
- 无条件分支
- 条件分支
如果仔细观察一个方法,你会发现方法是一个命名语句块,通过调用该特定名称来执行。无条件分支是通过调用方法或调用break
、continue
、return
或throw
创建的,这些将在下面介绍。
当在流程中遇到另一个方法的名称时,它会在当前方法中停止执行并分支到新调用的方法。从调用的方法返回一个值后,执行将从调用方法下面一行的原始方法恢复。
|
|
程序流程从main
方法开始。就像调用aMethod
一样,流程会移动到被调用的方法。此时,流程分支到另一个方法。方法完成后,流程返回到它离开的位置,并在调用方法后的下一条语句处继续。
返回语句
[edit | edit source]一个return
语句退出一个块,因此它通常是方法的最后一条语句。
代码部分 3.9:一个返回语句。
public int getAge() {
int age = 24;
return age;
}
|
返回语句可以返回一个变量的内容或什么都不返回。注意不要在返回语句之后编写不会被执行的语句!每个return
语句都以分号 (;
) 结尾。
条件分支语句
[edit | edit source]条件分支是借助if...else
和switch
语句实现的。只有当某个条件表达式计算结果为 true 时,才会发生条件分支。
条件语句
[edit | edit source]也称为if
语句,它们允许程序执行测试,然后根据测试结果采取行动。
if
语句的形式
if
(condition) { do statements here if condition is true }else
{ do statements here if condition is false }
条件是一个布尔表达式,它可以是true
或false
。执行的操作将取决于条件的值。
示例
代码部分 3.10:一个 if 语句。
if (i > 0) {
System.out.println("value stored in i is greater than zero");
} else {
System.out.println("value stored is not greater than zero");
}
|
使用 else if 组合可以使 if 语句更复杂
if
(condition 1) { do statements here if condition 1 is true }else
if
(condition 2) { do statements here if condition 1 is false and condition 2 is true }else
{ do statements here if neither condition 1 nor condition 2 is true }
示例
代码部分 3.11:一个 if/else if/else 语句。
if (i > 0) {
System.out.println("value stored in i is greater than zero");
} else if (i < 0) {
System.out.println("value stored in i is less than zero");
} else {
System.out.println("value stored is equal to 0");
}
|
如果在条件之后只有一条语句要执行,如上面的例子,可以省略花括号,但 Oracle 的 Java 代码约定 明确说明应始终使用花括号。
if 语句中没有循环,因此一旦条件被评估,程序将继续执行语句后的下一条指令。
If...else 语句
[edit | edit source]if
... else
语句用于根据布尔条件的结果有条件地执行两个语句块中的一个。
示例
代码部分 3.12:一个 if/else 语句。
if (list == null) {
// This block of statements executes if the condition is true.
} else {
// This block of statements executes if the condition is false.
}
|
Oracle 的 Java 代码约定 建议始终使用花括号。
一个if
语句有两种形式
if
(boolean-condition)
statement1
和
if
(boolean-condition) statement1else
statement2
如果需要在布尔条件为 true 或 false 时执行不同的语句,则使用第二种形式。如果只想在条件为 true 时执行statement1,并且不想在条件为 false 时执行备用语句,则使用第一种形式。
代码部分 3.13调用两个int
方法,f()
和y()
,存储结果,然后使用一个if
语句来测试x
是否小于y,如果是,则statement1主体将交换值。最终结果是 x 始终包含较大的结果,y 始终包含较小的结果。
代码部分 3.13:值交换。
int x = f();
int y = y();
if (x < y) {
int z = x;
x = y;
y = z;
}
|
if
...else
语句也允许使用另一个语句,else
if
。此语句用于为条件提供另一个if
语句,该语句只有在其他语句不为 true 时才能执行。例如
代码部分 3.14:多路分支。
if (x == 2)
x = 4;
else if (x == 3)
x = 6;
else
x = -1;
|
else
if
语句在这种情况下很有用,因为如果其中一个条件为 true,则另一个条件必须为 false。请记住,如果一个为 true,则另一个不会执行。例如,如果第一条条件语句中第 2 行的语句更改为x = 3;
,则第二个条件语句,else
if
,仍然不会执行。但是,在处理条件语句中的基本类型时,最好使用switch 语句
,而不是多个else
if
语句。
switch 语句
[edit | edit source]switch
条件语句基本上是编写许多if
...else
语句的简写。switch
语句的语法如下
switch
(<variable>) {
case <result>: <statements>; break;
case <result>: <statements>; break;
default: <statements>; break;
}
这意味着,如果包含的变量等于 case 结果之一,则会执行该 case 之后直到 break
关键字之间的语句。如果其他 case 都为假,则执行 default
case。注意:只有 switch
语句可以分析的类型是 char
、byte
、short
或 int
原生类型。这意味着 Object
变量不能通过 switch
语句进行分析。但是,从 JDK 7 版本开始,你可以在 switch 语句的表达式中使用 String 对象。
代码部分 3.15:一个 switch。
int n = 2, x;
switch (n) {
case 1: x = 2;
break;
case 2: x = 4;
break;
case 3: x = 6;
break;
case 4: x = 8;
break;
}
return x;
|
在这个例子中,由于整型变量 n
等于 2,所以 case 2
会执行,使 x
等于 4。因此,该方法返回 4。
迭代语句
[edit | edit source]迭代语句用于迭代语句块。这些语句通常被称为循环。Java 提供了四种迭代语句。
while
循环do...while
循环for
循环foreach
循环
while 循环
[edit | edit source]while
循环在它指定的条件为 true
时迭代代码块。
循环的语法为
while
(condition) {
statement;
}
这里条件是一个表达式。如前所述,表达式是任何返回值的语句。while
条件语句评估为布尔值,即 true
或 false
。只要条件为 true
,循环就会一遍又一遍地迭代代码块。一旦条件评估为 false
,循环就会退出到循环之外的下一条语句。
do...while 循环
[edit | edit source]do-while 循环在功能上类似于 while 循环,除了条件在语句执行之后评估。
do
{ statement; }while
(condition);
for 循环
[edit | edit source]for 循环是一个专门的 while 循环,其语法旨在轻松迭代数字序列。示例
|
|
程序打印了 0 到 99 的数字及其平方。
while 循环中的相同语句
代码部分 3.17:一个替代版本。
int i = 0;
while (i < 100) {
System.out.println(i + "\t" + i * i);
i++;
}
|
foreach 循环
[edit | edit source]foreach 语句允许你遍历集合中的所有项目,依次检查每个项目,同时保留其类型。foreach 语句的语法为
for
(type item : collection) statement;
例如,我们将使用一个 String
数组,表示一周中的几天,并遍历该集合,一次检查一个项目。
|
|
请注意,循环在集合中的最后一个项目在语句块中被检查后会自动退出。
虽然增强的 for 循环可以使代码更清晰,但它不能在一些常见的情况下使用。
- 只读访问。元素不能被赋值,例如,不能递增集合中的每个元素。
- 仅单个结构。不可能同时遍历两个结构,例如,比较两个数组。
- 仅单个元素。仅用于访问单个元素,例如,不能比较相邻的元素。
- 仅向前。只能以单个步长向前迭代。
- 至少是 Java 5。如果你需要与 Java 5 之前的版本兼容,请不要使用它。
continue 和 break 语句
[edit | edit source]有时,你可能希望重新迭代循环,而不执行循环中剩余的语句。
语句会导致循环重新迭代,并从循环中最顶部的语句开始。continue
如果有重新迭代循环的能力,那么就存在退出循环的能力。在任何时候,如果你想退出循环并结束循环中的所有进一步操作,则应该使用
。break
和 continue
语句可以与标签一起使用,如下所示break
代码部分 3.19:使用标签。
String s = "A test string for the switch!\nLine two of test string...";
outer: for (int i = 0; i < s.length(); i++) {
switch (s.charAt(i)) {
case '\n': break outer;
case ' ': break;
default: System.out.print(s.charAt(i));
}
}
|
代码清单 3.19 的输出
Ateststringfortheswitch! |
throw 语句
[edit | edit source]throw
语句会退出方法,等等,或者被 try
/catch
块捕获。它不返回变量,而返回异常
代码部分 3.20:一个 return 语句。
public int getAge() {
throw new NullPointerException();
}
|
注意不要在 throw
语句之后编写不会执行的语句!每个 throw
语句都以分号 (;
) 结尾。
try/catch
[edit | edit source]try
/catch
至少必须包含 try
块和 catch
块
代码部分 3.21:try/catch 块。
try {
// Some code
} catch (Exception e) {
// Optional exception handling
} finally {
// This code is executed no matter what
}
|
问题 3.1:这个类中有多少个语句?
代码清单 3.2:AProgram.java
public class AProgram {
private int age = 24;
public static void main(String[] args) {
int daysInAYear = 365;int ageInDay = 100000;
int localAge = ageInDay / daysInAYear;
}
public int getAge() {
return age;
}
}
|
5
第 3 行有一个语句,第 6 行有两个语句,第 7 行有一个语句,第 11 行有一个语句。