跳转到内容

语句

100% developed
来自维基教科书,开放世界中的开放书籍

导航 语言基础 主题: v  d  e )


现在我们已经将 Java 平台安装到了系统上,并且成功运行了第一个程序,接下来我们将了解程序是如何编写的。正如我们之前讨论的,程序是一组指令,即提供给计算机的任务。在 Java 中,这些指令被称为 **语句**。语句可以是单行代码,也可以是复杂的数学方程式。考虑以下代码行

Example 代码节 3.1:简单的赋值语句。
int age = 24;

这行代码是一个简单的指令,它告诉系统初始化一个变量并将其值设置为 24。如果上述语句是程序中唯一的语句,它将类似于下面这样

Computer code 代码列表 3.1:简单类中的语句。
public class MyProgram
 {
    public static void main(String[] args) 
    {
        int age = 24;
    }
}

Java 将其语句放在类声明中,在类声明中,语句通常放在方法声明中,如上所示。

变量声明语句

[编辑 | 编辑源代码]

最简单的语句是变量声明

Example 代码节 3.2:简单的声明语句。
int age;

它定义了一个变量,该变量可以用来存储值以供以后使用。第一个标记是变量的 数据类型(该变量可以存储哪种类型的值)。第二个标记是变量的名称,您将通过它来引用该变量。然后每个声明语句都以分号 (;) 结尾。

赋值语句

[编辑 | 编辑源代码]

到目前为止,我们一直假设变量的创建是一个单独的语句。实质上,我们为这些变量分配一个值,这就是它的名称。当您在语句中为变量分配一个值时,该语句被称为 **赋值语句**(也称为 初始化语句)。您是否注意到还有一件事?是分号 (;),它位于每个语句的末尾。明确表明一行代码是语句的标志是它以分号结尾。如果要编写多个语句,通常会将每个语句放在单独一行,并以分号结尾。考虑以下示例

Example 代码节 3.3:多个赋值语句。
int a = 10;
int b = 20;
int c = 30;

您不必一定要使用新行来编写每个语句。就像英语一样,您可以从结束第一个语句的地方开始编写下一个语句,如下所示

Example 代码节 3.4:同一行上的多个赋值语句。
int a = 10; int b = 20; int c = 30;

但是,将多个语句放在同一行中的唯一问题是,它非常难读。起初它看起来并不那么吓人,但一旦您拥有大量的代码,通常最好以一种有意义的方式来组织它。如果按照代码列表 3.4 中的写法,它看起来会更加复杂和难以理解。

现在我们已经了解了简单的赋值语句的结构,我们可以回顾一下我们所取得的成就。我们知道...

  • 语句是编程中代码的单位。
  • 如果我们要为变量分配一个值,则该语句被称为赋值语句。
  • 赋值语句包括三个部分:数据类型、变量名(也称为标识符)和变量的值。我们将在后面的“变量”部分详细介绍标识符和值的性质。

现在,在我们继续下一个主题之前,您需要尝试理解以下代码的作用。

Example 代码节 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 赋值后,如果我们为 firstNumbersecondNumber 分配不同的值,如第 5 行所示,它的值不会改变。

有了您刚刚获得的信息,您实际上可以编写一个可以将值加起来的不错的 Java 程序。

断言检查条件是否为真

Example 代码节 3.6:返回语句。
    public int getAge() 
    {
        assert age >= 0;
        return age;
    }

每个 assert 语句都以分号 (;) 结尾。但是,断言默认情况下是禁用的,因此您必须使用 -ea 参数运行程序才能启用断言 (java -ea [已编译程序的名称])。

程序控制流

[编辑 | 编辑源代码]

语句按照其出现的顺序进行求值。执行流从最上面的语句开始,向下进行,直到遇到最后一个语句。语句可以被语句块替换。有一些特殊的语句可以根据条件重定向执行流,这些语句被称为 **分支** 语句,将在后面的部分详细介绍。

语句块

[编辑 | 编辑源代码]

一组语句可以放在花括号中,作为单个块执行。这样的语句块可以命名,也可以为执行提供条件。以下是将一系列语句放在块中的方法。

Example 代码节 3.7:语句块。
{
    int a = 10;
    int b = 20;
    int result = a + b;
}

分支语句

[编辑 | 编辑源代码]

可以使用函数/方法调用、循环和迭代来影响程序流。在各种类型的分支结构中,我们可以轻松地挑选出两种通用的分支方法。

  • 无条件分支
  • 条件分支

无条件分支语句

[编辑 | 编辑源代码]

如果仔细观察一个方法,你会发现方法是一个命名语句块,通过调用该特定名称来执行。无条件分支是通过调用方法或调用breakcontinuereturnthrow创建的,这些将在下面介绍。

当在流程中遇到另一个方法的名称时,它会在当前方法中停止执行并分支到新调用的方法。从调用的方法返回一个值后,执行将从调用方法下面一行的原始方法恢复。

Computer code 代码清单 3.8:UnconditionalBranching.java
public class UnconditionalBranching {
    public static void main(String[] args) {
        System.out.println("Inside main method! Invoking aMethod!");
        aMethod();
        System.out.println("Back in main method!");
    }

    public static void aMethod() {
        System.out.println("Inside aMethod!");
    }
}
Standard input or output 运行上述代码时,提供的信息屏幕输出。
Inside main method! Invoking aMethod!
Inside aMethod!
Back in main method!

程序流程从main方法开始。就像调用aMethod一样,流程会移动到被调用的方法。此时,流程分支到另一个方法。方法完成后,流程返回到它离开的位置,并在调用方法后的下一条语句处继续。

返回语句

[edit | edit source]

一个return语句退出一个块,因此它通常是方法的最后一条语句。

Example 代码部分 3.9:一个返回语句。
    public int getAge() {
        int age = 24;
        return age;
    }

返回语句可以返回一个变量的内容或什么都不返回。注意不要在返回语句之后编写不会被执行的语句!每个return语句都以分号 (;) 结尾。

条件分支语句

[edit | edit source]

条件分支是借助if...elseswitch语句实现的。只有当某个条件表达式计算结果为 true 时,才会发生条件分支。

条件语句

[edit | edit source]

也称为if语句,它们允许程序执行测试,然后根据测试结果采取行动。

if语句的形式

if (condition) {
  do statements here if condition is true
} else {
  do statements here if condition is false
}

条件是一个布尔表达式,它可以是truefalse。执行的操作将取决于条件的值。

示例

Example 代码部分 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
}

示例

Example 代码部分 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 语句用于根据布尔条件的结果有条件地执行两个语句块中的一个。

示例

Example 代码部分 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)
   statement1
else
   statement2

如果需要在布尔条件为 true 或 false 时执行不同的语句,则使用第二种形式。如果只想在条件为 true 时执行statement1,并且不想在条件为 false 时执行备用语句,则使用第一种形式。

代码部分 3.13调用两个int方法,f()y(),存储结果,然后使用一个if语句来测试x是否小于y,如果是,则statement1主体将交换值。最终结果是 x 始终包含较大的结果,y 始终包含较小的结果。

Example 代码部分 3.13:值交换。
int x = f();
int y = y();
if (x < y) {
  int z = x;
  x = y;
  y = z;
}

if...else语句也允许使用另一个语句,else if。此语句用于为条件提供另一个if语句,该语句只有在其他语句不为 true 时才能执行。例如

Example 代码部分 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 语句可以分析的类型是 charbyteshortint 原生类型。这意味着 Object 变量不能通过 switch 语句进行分析。但是,从 JDK 7 版本开始,你可以在 switch 语句的表达式中使用 String 对象。

Example 代码部分 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 条件语句评估为布尔值,即 truefalse。只要条件为 true,循环就会一遍又一遍地迭代代码块。一旦条件评估为 false,循环就会退出到循环之外的下一条语句。

do...while 循环

[edit | edit source]

do-while 循环在功能上类似于 while 循环,除了条件在语句执行之后评估。

do {
   statement;
 } while (condition);

for 循环

[edit | edit source]

for 循环是一个专门的 while 循环,其语法旨在轻松迭代数字序列。示例

Example 代码部分 3.16:一个 for 循环。
for (int i = 0; i < 100; i++) {
  System.out.println(i + "\t" + i * i);
}
Standard input or output 如果你编译并运行上面的语句,代码清单 3.16 的输出。
 0      0
 1      1
 2      4
 3      9
 ...
 99     9801

程序打印了 0 到 99 的数字及其平方。

while 循环中的相同语句

Example 代码部分 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 数组,表示一周中的几天,并遍历该集合,一次检查一个项目。

Example 代码部分 3.18:一个 foreach 循环。
String[] days = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

for (String day : days) {
  System.out.println(day);
}
Standard input or output 代码清单 3.18 的输出
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

请注意,循环在集合中的最后一个项目在语句块中被检查后会自动退出。

虽然增强的 for 循环可以使代码更清晰,但它不能在一些常见的情况下使用。

  • 只读访问。元素不能被赋值,例如,不能递增集合中的每个元素。
  • 仅单个结构。不可能同时遍历两个结构,例如,比较两个数组。
  • 仅单个元素。仅用于访问单个元素,例如,不能比较相邻的元素。
  • 仅向前。只能以单个步长向前迭代。
  • 至少是 Java 5。如果你需要与 Java 5 之前的版本兼容,请不要使用它。

continue 和 break 语句

[edit | edit source]

有时,你可能希望重新迭代循环,而不执行循环中剩余的语句。continue 语句会导致循环重新迭代,并从循环中最顶部的语句开始。

如果有重新迭代循环的能力,那么就存在退出循环的能力。在任何时候,如果你想退出循环并结束循环中的所有进一步操作,则应该使用 break

continuebreak 语句可以与标签一起使用,如下所示

Example 代码部分 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));
  }
}
Standard input or output 代码清单 3.19 的输出
 Ateststringfortheswitch!

throw 语句

[edit | edit source]

throw 语句会退出方法,等等,或者被 try/catch 块捕获。它不返回变量,而返回异常

Example 代码部分 3.20:一个 return 语句。
    public int getAge() {
        throw new NullPointerException();
    }

注意不要在 throw 语句之后编写不会执行的语句!每个 throw 语句都以分号 (;) 结尾。

try/catch

[edit | edit source]

try/catch 至少必须包含 try 块和 catch

Example 代码部分 3.21:try/catch 块。
try {
  // Some code
} catch (Exception e) {
  // Optional exception handling
} finally {
  // This code is executed no matter what
}
测试你的知识

问题 3.1:这个类中有多少个语句?

Computer code 代码清单 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 行有一个语句。


华夏公益教科书