《21天学通Java(第7版)》—— 2.5 表达式和运算符

简介: int x = 3; int y = x; int z = x * y; 这3条语句都是表达式——它们提供了可被赋给变量的值。第1条语句将字面量3赋给变量x。第2条语句将变量x的值赋给变量y。在第3条语句中,乘法运算符*用来将x和y相乘,结果存储在变量z中。

本节书摘来异步社区《21天学通Java(第7版)》一书中的第2章,第2.5节,作者: 【美】Rogers Cadenhead(罗格斯 卡登海德),更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.5 表达式和运算符

表达式是一条能够提供值的语句。最常见的是数学表达式,如下面的例子所示:

int x = 3;
int y = x;
int z = x * y;

这3条语句都是表达式——它们提供了可被赋给变量的值。第1条语句将字面量3赋给变量x。第2条语句将变量x的值赋给变量y。在第3条语句中,乘法运算符*用来将x和y相乘,结果存储在变量z中。

表达式可以是变量、字面量和运算符的任何组合,也可以是方法调用,因为方法能够将一个值返回给调用它的类或对象。

您知道,表达式所提供的值称为返回值。在Java程序中,可将这个值赋给变量或以其他方式使用。

大多数Java中的表达式使用了运算符,如*。运算符是一些特殊符号,用于数学函数、赋值语句和逻辑比较。

2.5.1 算术运算符

在Java中,有5种用来完成基本算术运算的运算符,如表2.3所示。

6a82057bff8d2ebdb64093865a1bc368057076f4

每个运算符都有两个操作数,一边一个。减法运算符也可以用来对单个操作数求反,即将操作数与−1相乘。

使用除法时,要注意操作数的类型。如果将除法运算的结果存储在整型变量中,结果将向下取整,因为int类型不能处理浮点数。

例如,如果将结果存储在int变量中,则表达式31/9的结果为3。

使用运算符%的求模运算得到的是除法运算的余数。例如,31%9的结果是4,因为31被9除的余数是4。

很多针对整数的算术运算的结果为int值,而不管操作数是什么类型。处理其他数值类型,如浮点数或长整型时,应确保操作数的类型与所需结果的类型相同。

要创建的下一个项目是个Java类,它演示了如何使用Java执行简单的算术运算。为此,在NetBeans中新建一个空Java文件,将其命名为Weather并放在com.java21days包中,再在源代码编辑器中输入程序清单2.2所示的代码。输入完毕后选择菜单“文件”>“保存”将这个文件存盘。

程序清单2.2 源代码文件Weather.java

1: package com.java21days;
2:
3: public class Weather {
4:      public static void main(String[] arguments) {
5:           float fah = 86;
6:           System.out.println(fah + " degrees Fahrenheit is ...");
7:           // To convert Fahrenheit into Celsius
8:           // begin by subtracting 32
9:           fah = fah - 32;
10:          // Divide the answer by 9
11:          fah = fah / 9;
12:          // Multiply that answer by 5
13:          fah = fah * 5;
14:          System.out.println(fah + " degrees Celsius\n");
15:
16:          float cel = 33;
17:          System.out.println(cel + " degrees Celsius is ...");
18:          // To convert Celsius into Fahrenheit
19:          // begin by multiplying by 9
20:          cel = cel * 9;
21:          // Divide the answer by 5
22:          cel = cel / 5;
23:          // Add 32 to the answer
24:          cel = cel + 32;
25:          System.out.println(cel + " degrees Fahrenheit");
26:      }
27: }

选择菜单“运行”>“运行文件”运行该程序,它将生成如图2.2所示的输出。

439378d359f2b81c0a458e5e839e4322a5fc7c52

该Java应用程序的第5~14行使用算数运算符将华氏温度转换为摄氏温度。

第5行:声明浮点变量fah,并将其初始化为86。
第6行:显示fah的当前值。
第7行:第一个注释,解释了该程序的功能。这些注释将被Java编译器忽略。
第9行:将fah的值减去32。
第11行:将fah的值除以9。
第13行:将fah的值乘以5。
第14行:将fah的值转换为摄氏温度后,再次显示它。
第16~25行与此类似,但执行相反的转换——将摄氏温度转换为华氏温度。

2.5.2 再谈赋值

给变量赋值的语句是一个表达式,因为它生成一个值。因此,可以下面这种不同寻常的方式将赋值语句连在一起:

x = y = z = 7;
在这条语句中,所有3个变量(x、y和z)的值最后都为7。

在赋值之前,将首先计算赋值表达式的右边。因此,可以这样使用表达式语句:

int x = 5;
x = x + 2;

在表达式x = x + 2中,首先计算x+2;然后将结果(7)赋给变量x。

在编程中,使用表达式来修改变量的值是一项常见的任务。有几个专门用于这方面的运算符。

表2.4列出了这些赋值运算符及等效的表达式。

f64c433fc9166209d21a8ade88b81f2a55e52efd

这些简化的赋值运算符与它们所代表的更长的赋值语句等效。然而,如果赋值语句的一边是复杂的表达式,将出现不再等效的情况。例如,如果x等于20,y等于5,下面两条语句的结果将不同:

x = x / y + 5;
x /= y + 5;

其中第一条语句导致x的值为9,而第二条语句导致x的值为2。有疑问时,应使用多条赋值语句来简化表达式,而不要使用简化的运算符。
2.5.3 递增和递减运算符
另一种常见的编程任务将整型变量加1或减1。有专门用于完成这种运算的运算符:递增和递减运算符。对变量做递增运算意味着将它的值加1,做递减运算意味着将它的值减1。

递增运算符是++,递减运算符是−−。这些运算符位于变量名的前面或后面,如下所示:

int x = 7;
x++;

其中语句x++将变量x的值从7增加到8。

递增和递减运算符可放在变量名的前面或后面,这将影响表达式的结果。

如果递增和递减运算符位于变量名前面,则被称为前缀运算符;如果位于变量名后面,则被称为后缀运算符。

在简单表达式(如counts--;)中,无论使用前缀还是后缀运算符,结果都相同,因此它们可以互换。然而,当递增和递减运算符被用于更复杂的表达式中时,选择前缀还是后缀运算符就至关重要。

请看下面的代码:

int x, y, z;
x = 42;
y = x++;
z = ++x;

上述3个表达式由于前缀和后缀运算符的差别而产生完全不同的结果。

使用后缀运算符时,先使用变量的值,再将变量递增或递减。因此,在y = x++中,先将x的值赋给y,再将x的值加1。

使用前缀运算符时,先将变量递增或递减,再使用变量的值。例如,在z = ++x中,先将x的值加1,再将x的值赋给z。

上述代码的最终结果是,y等于42,z等于44,x等于44。

如果对此还不清楚,下面的例子再次通过注释描述了每一步的情况:

int x, y, z; // x, y, and z are declared
x = 42;        // x is given the value 42
y = x++;       // y is given x's value (42) before it is incremented
                     // and x is then incremented to 43
z = ++x;        // x is incremented to 44, and z is given x's value

在特别复杂的表达式中使用递增和递减运算符时,很可能得到意外的结果。“在x自增之前将x的值赋给y”这一概念不再完全正确,因为Java总是先计算表达式右边的内容,然后再把结果赋给表达式左边的变量。Java在处理表达式之前会存储一些值,以便后缀运算符能够像本节介绍的那样工作。当包含前缀和后缀运算符的复杂表达式的结果不同于您的期望时,请将该表达式拆成多个语句,以简化它。

2.5.4 比较运算符

Java有几种可用于对变量之间、变量和字面量(或其他类型的信息)之间进行比较的运算符。

这些运算符用于返回布尔值(true或false)的表达式,表达式的返回值取决于比较的结果是真还是假。表2.5列出了这些比较运算符。

0d1207d7a747f0b1039989d21622fb37436240a7

下面的例子演示了比较运算符的用法:

boolean isHip;
int age = 37;
isHip = age < 25;

表达式age<25的结果为true还是false取决于age的值。由于这里的age为37(比25大),因此isHip为布尔值false。

2.5.5 逻辑运算符

结果为布尔值的表达式(如比较运算)可以被组合成更加复杂的表达式。这是通过逻辑运算符来实现的,逻辑运算符用于逻辑组合:AND、OR、XOR和逻辑NOT。

对于AND组合,可使用逻辑运算符&或&&。当两个布尔表达式通过&或&&组合在一起后,仅当两个布尔表达式都为真时,整个表达式的结果才为true。

请看下面的例子:

boolean extraLife = (score > 75000) & (playerLives < 10);
这个表达式将两个比较表达式(score > 75000和playerLives <10)组合在一起。如果这两个表达式都为真,则true被赋给变量extraLife;在其他情况下,false被赋给extraLife。

&和&&之间的差别在于Java对组合表达式所做的工作量。如果使用&,则不管什么情况下,&两边的表达式都将被计算;如果使用&&,则当左边的表达式为false时,将不计算右边的表达式。

因此,&&的效率更高,因为它不做不必要的工作。在前面的示例中,如果score不比75000大,就根本不需要考虑playLives是否小于10。

对于OR组合,可使用逻辑运算符|或||。如果运算符两边的任何一个布尔表达式为真,则组合表达式的结果为true。

请看下述示例:

boolean extralife = (score > 75000) || (playerLevel == 0);
该表达式合并了两个比较表达式:score > 75000和playerLevel = = 0。只要这两个表达式中的任何一个为真,则true被赋给变量extraLife;仅当这两个表达式都是false时,false才被赋给extraLife。

注意,这里使用的是||,而不是|。因此,如果score > 75000为true,则extraLife将被设置成true,而根本不会计算第二个表达式。

用于XOR合并的逻辑运算符只有一个:^。仅当被合并的两个布尔表达式的值相反时,整个表达式的结果才为true;如果两个表达式都是true或都是false,则^运算符的结果为false。

NOT组合使用逻辑运算符!,后面跟一个表达式。它对布尔表达式的值求反,这与用负号来改变数字的符号相同。例如,如果age<25的结果为true,则!(age<25)的结果将为false。

首次见到这些逻辑运算符时,可能觉得它们完全不符合逻辑。在本周余下的课程中,您将大量地使用它们,尤其是在第5章。

2.5.6 运算符优先级

当表达式中有多个运算符时,Java有一套优先级用来判断运算符的执行顺序。在许多情况下,优先级决定了整个表达式的最终值。

例如,请看下面的表达式:

y = 6 + 4 / 2;
变量y的值为5还是8取决于哪个算术运算先被处理。如果先计算表达式6+4,则y的值为5;否则为8。

通常,从先到后的顺序如下:

  • 1.递增和递减运算;
  • 2.算术运算;
  • 3.比较运算;
  • 4.逻辑运算;
  • 5.赋值运算。

如果两个运算的优先级相同,则左边的比右边的先被处理。表2.6列出了Java中众多运算符的优先级。排在越前面的运算符的优先级越高。

56c11f8b7664cfc9ef8070b116ed28e35c028815 b6d92f63977905449e793d36e148762da045e4c6

表2.6中的多个运算符都将在本周后面的课程中介绍。

回过头来看表达式y =6 + 4 / 2。表2.6表明,除法先于加法计算,因此y的值为8。

要改变表达式求值的顺序,可以用圆括号将需要先计算的表达式括起。可以嵌套圆括号以确保按所需的顺序对表达式进行求值——最里边的圆括号内的表达式最先被计算。

下述表达式的结果为5:

y = (6 + 4) / 2
因为先计算6 + 4,得到10,然后再除以2,最后的结果为5。

圆括号还可以提高表达式的可读性。如果不能一眼看出表达式的优先级,可以添加圆括号来强制转换为希望的优先级,使语句更容易理解。

相关文章
|
24天前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
25 0
|
11天前
|
XML 数据可视化 前端开发
java正则表达式
java正则表达式
|
9天前
|
Java
Java 运算符
4月更文挑战第8天
|
3天前
|
分布式计算 Java API
Java 8新特性之Lambda表达式与Stream API
【4月更文挑战第16天】本文将介绍Java 8中的两个重要新特性:Lambda表达式和Stream API。Lambda表达式是Java 8中引入的一种新的编程语法,它允许我们将函数作为参数传递给其他方法,从而使代码更加简洁、易读。Stream API是Java 8中引入的一种新的数据处理方式,它允许我们以声明式的方式处理数据,从而使代码更加简洁、高效。本文将通过实例代码详细讲解这两个新特性的使用方法和优势。
|
7天前
|
Java
Java 14 强势登场:Switch 表达式的进化之路
Java 14 强势登场:Switch 表达式的进化之路
13 0
|
9天前
|
Java 开发者
Java中的Lambda表达式:简洁、灵活的编程利器
在现代软件开发中,编写简洁、高效的代码是至关重要的。Java中的Lambda表达式为开发者提供了一种简洁、灵活的编程方式,使得代码更具可读性和可维护性。本文将探讨Lambda表达式的基本概念、语法结构以及在实际项目中的应用,以帮助读者更好地理解和运用这一强大的编程工具。
5 0
|
11天前
|
存储 Java API
java8新特性 lambda表达式、Stream、Optional
java8新特性 lambda表达式、Stream、Optional
|
11天前
|
Java
Java_运算符
该文档介绍了编程中的几种运算符。算术运算符包括加、减、乘、除和取余
14 1
|
23天前
|
Java API
Java中的Lambda表达式和函数式编程
传统的Java编程方式在处理一些简单的逻辑时显得繁琐,而Lambda表达式的引入为我们提供了一种更加简洁、灵活的编程方式。本文将介绍Lambda表达式和函数式编程在Java中的应用以及其与传统编程方式的对比,帮助读者更好地理解并运用这一特性。
7 0
|
25天前
|
Java API 开发者
Java中的Lambda表达式及其应用
本文将介绍Java中的Lambda表达式,探讨其在函数式编程中的作用和应用。通过对Lambda表达式的语法、特点以及实际应用场景的详细分析,读者将能够更好地理解并运用Lambda表达式,从而提高代码的简洁性和可读性。
18 1