本文是《Java学习指南》原书的网络版,作者邵发,拥有本书的全部权利。相关视频课程在此查看。
目录
第3章 操作符与表达式
3.1 算术操作符
本节学习以下5个操作符,用于实现算术运算。
操作符 | 名称 | 作用 |
+ | 加 | 加法运算 |
- | 减 | 减法运算 |
* | 乘 | 乘法运算 |
/ | 除 | 除法运算 |
% | 模 | 模运算 |
这几个符号其实和小学算术里的内容是基本对应的,有区别的是除法和模。
3.1.1 整型的算术运算
以下式子中,a,b为int型
a + b 求和
a - b 求差
a * b 求积
a / b 求商 (结果不保留小数)
a % b 求余
规定两个int型在算术运算后,结果仍为int型。运算规则和小学算术基本一样,下面只需要解释一下除法和模。
(1) 整型的除法运算,结果舍去小数部分
例如,14 / 5 的值为 2
System.out.println( "结果为: " + ( 14 / 5 ));
(2) 整型的模运算,结果为余数
例如,14 % 5 的值为 4
System.out.println( "结果为: " + ( 14%5 ));
3.1.2 浮点型的算术运算
对于小数的算术运算,其规则也没什么难度。下面重点注意一下它的除运算和模运算。
(1) 浮点型的除法运算,结果保留小数部分
例如,14.0 / 5.0 的值为 2.8
System.out.println( "结果为: " + ( 14.0 / 5.0 ));
(2) 浮点型的模运算,结果为余数
例如,
14.0 % 5.0 的值为 4.0
System.out.println( "结果为: " + ( 14.0 % 5.0 ));
3.1.3 区分
以下式子的结果为什么不同?
14 / 5
14.0 / 5.0
其中,
14/5 ,是两个int型的运算,所以结果仍然为int型,值为2
14.0 / 5.0 ,是两个double型的运算,所以结果仍然为double型,值为2.8
3.1.4 类型提升
考虑以下式子:
int a = 14;
double b = 5.0;
System.out.println( "结果为: " + ( a / b) );
一个int型与一个double型进行除法运算,那么结果是2还是2.8呢?
规定:当int型与double型混合运算时,把int型视为double型,称为类型的提升。
这是因为,double型是可以兼容整数的表示的,所以都提升为double型来运算比较好,不会丢失数据。
所以,上式 a/b 的结果按double/double来进行,结果为2.8。
3.1.5 混合运算与优先级
当一个式子中包含多种符号时,需要考虑优先级问题。
一个最简单的例子,
a* b + c / d
这个式子里有3种运算符:乘、加、除。那么,在运算的时候,谁先进行、谁后进行是一个问题。
和我们所直观理解的一致,乘、除的优先级是略高于加的。所以,它在运算的时候,是按以下的顺序
① a*b
② c/d
③ 上两式结果相加 , 即 (a * b) + (c /d )
通过这个小例子,我们可以感受到优先级的问题。在Java语言里,规定了* 和 / 的优先级要高于 + ,所以才有了上面的结果。
3.1.6 表达式与操作符
操作符,operator, 也称为运算符。比如 + - * / 这些符号。
表达式,expression,就是一个由数值和操作符组成的式子。把所有的变量的值代入表达式,计算出的最终的值,就叫表达式的值。
例如,
12 + 3 的值为15,类型为int
12.0 + 3 的值为15.0 ,类型为 double
3.2 关系操作符
本节学习以下几个操作符,用于表示数值的大小关系。
操作符 | 名称 | 作用 |
< | 小于 |
|
<= | 小于或等于 |
|
> | 大于 |
|
>= | 大于或等于 |
|
== | 等于 |
|
!= | 不等于 |
|
关系表达式的值为boolean类型。
例如:
int a = 10, b=4;
boolean result = a > b;
System.out.println (" 结果: " + result );
其中,将a,b的值代入表达式值,计算得result的值为 true ,所以以上代码输出为:
3.2.1 关系操作符的运算
对于关系表达式,只需要所相应的值代入式子,从逻辑上判断一下。如果是成立的,则值为true;如果不成立,则值为false。
例如,
( 10 > 4 ) ,此式成立,所以其值为true
例如,设a为10,
( a < 5) ,此式不成立,所以其值为false
可以直接在println()里打印输出一下,
int a = 10;
System.out.println (" 结果: " + ( a < 5) );
注意,在println里的表达式要加上小括号。
3.2.2 更多练习
以下表达式的值是?
4 > 5 false
4 >= 4 true (注: >= 表示大于或等于 )
3 < 4 true
3 != 4 true
3 != 3 false
8 == 7 false
8 == 8 true
以下表达式的值是?假设 int a = 8, b= 7;
a > 8 false
a == b false
a <= b false
a >= b + 1 true
以下表达式的值是?假设 double a=11.2, b=1;
a > 8 true
a == b false
a <= b false
a >= b + 1 true
再重复一下关系表达式的运算规则:只需要把变量的值代入式子,看成不成立;成立则为true, 否则为false。
3.2.3 注意事项
(1) 操作符是一个整体,中间不能加空格
例如 >= <= == !=
(2) 对于初学者来说,注意区分 == 和 =
编程并不是数学,不要把数学的习惯带过来。当判断是否相等时,要用 == 。
3.3 逻辑操作符
本节学习以下几个操作符,用于判断逻辑关系。
操作符 | 名称 | 作用 |
&& | 逻辑与 | 并且 |
|| | 逻辑或 | 或者 |
! | 逻辑非 | 非 |
3.3.1 逻辑与 &&
这个操作符用于表示“并且”的关系。规则如下,
a && b
当a成立并且b成立时,结果才成立(true)。否则,结果不成立(false)。
其中,a,b均为boolean类型。
通俗的讲,就是表示日常生活中“并且”的逻辑。比如,一件事情需要a,b同时在场才能处理,那就是并且的关系。
练习:求表达式 (3 > 4) && (4 > 3) 的结果
① 按优先级先计算 3>4 为false, 4>3为true
② 原式即为 false && true ,所以结果为 false
3.3.2 逻辑或 ||
这个操作符用于表示“或者”的关系。规则如下,
a || b
当a成立或者成立时,结果成立(true)。否则,结果不成立(false)。
通俗的讲,就是表示日常生活中“或者”的逻辑。比如,一件事情a,b均能处理,则只要a在场或者b在场,这就是或者的关系。
练习 : 求表达式 3 >4 || 4 > 3 的值
① 按优先级先计算 3>4 为false, 4>3为true
② 原式即为 false || true ,所以结果为 true
3.3.3 逻辑非 !
逻辑非表示“否”,规则比较简单,
!a
如果a为true,则结果为false; 如果为false,则结果为true。
练习:求表达式 ! ( 3 > 4) 的值
① 按优先级先计算 3>4 为false
② 原式即为 ! false ,所以结果为 true
3.3.4 注意事项
(1) 操作符是一个整体,中间不能加空格
例如 && ||
(2) 操作符与操作数之间,可以加空格
比如,! k 也可以
3.4 赋值操作符
在Java语言里,等号称为赋值操作符。
例:
a = b + 100;
注意,不要把Java语言理解为数学。在Java里,这个等号的作用是“赋值”,即右侧的值赋给左边的变量。
要求:
- 等号左边必须是变量
- 将等号右边表达式的值,赋给左边的变量
3.4.1 区分初始值与赋值
在定义一个变量的时候,可以指定初始值。例如,
int a = 10; // 定义一个变量a,初始值为10
int b; // 如果未指定初始值,则初始值为0
下面演示什么是赋值操作,
int a = 10; // 此行的等号为初始化
int b = 22; // 此行的等号为初始化
a = b + 100; // 此行的等号表示赋值操作
3.4.2 理解赋值操作的过程
赋值操作分2步运行:①先计算等号右侧的式子的值,②再把右侧的值赋给左侧的变量。
例如,
int a = 10;
a = a + 99; // 重点理解这一行的赋值操作
System.out.println("a的值为 " + a );
我们来分析一下 a = a + 99 这一行, 实际上计算机是分两步来运算出结果的:
(1) 首先,计算出左侧表达式(a+99)的值,为109
(2) 然后,将右侧的值赋给左侧的变量,即a=109
3.4.3 组合赋值操作符
赋值操作符可以和其他操作符组合起来使用,例如,
a += b;
a -= b;
a *= b;
a /= b;
a %= b;
规则都是一样的,相当于: a = a + b
示例:
int a = 10;
a += 12; // 相当于 a = a + 12
System.out.println("现在a为: " + a);
所以,a的最终值为 22
3.4.4 常量
在Java里,用final表示常量。类比一下:变量,是可以变化的量;常量,是不能变化的量。
所以,以下代码会报错:
final double PI = 3.14; // 定义常量PI,初始值为3.14
PI = 3.0; // 错误! PI是final修饰的,其值不能修改!
不过,final不是我们的学习重点,了解即可。
提示:在后面的学习中,将不会对final作进一步介绍。也就是说,即便你不懂final也可以继续往下学习。后面的教程里不会使用final作演示教学。
3.5 自增操作符
在Java语言里,++ 称为自增操作符。例:
int a = 10;
a++;
System.out.println("现在a为: " + a);
其中,a ++ 可以理解为 a = a +1 。所以,最终a的值为11。
3.5.1 前置自增与后置自增
自增操作符有2种写法,写在前面的称为前置自增,写在后面叫后置自增。例如,
后置自增:
int b = 10;
a = b++ ;
后置自增时,先把b的值代入式子运算,之后再对b自增加1。所以,最终的结果a为10, b为11。
前置自增:
int b = 10;
a = ++b ;
前置自增时,先对b自增加1,然后再代入式子运算。
前置自增与后置自增分辨起来有点烧脑,但它不是我们学习的重点,所以不要在这个知识点上花太多时间。
通常,分为增加代码的可读性,可以分成2行书写。例如,
a = b;
b ++; // 消除可能的误解
3.5.2 自增操作符
同样的,还有一套自减操作符 -- ,例如,
a = b --;
由于++ 和 -- 不是重点内容,所以不再缀述。
3.6 操作符的优先级
当一个表达式里有多种操作符时,就是明确操作符的优先级。也就是说,哪些部分先运算,哪些部分后运算。比如,
a - b * 10 / 2
这个表达式看起来很简单。之所以我们会觉得简单,因为我们已经事先知道了算术符的优先级(小学就学过了嘛!)。
但是,当把多种Java操作符用在一起时,就不那么简单的。比如,
a>10 && !ok
对于这样的式子,存在关系操作符 > 和逻辑操作符 && ! 。要经行运算,就必须明确优先级。在这里,关系操作符比逻辑操作符的优先级高,而逻辑非又与逻辑与的优先级高。
所以,它的运算顺序是这样的:
( (a>10) && (!ok) )
先运算 a>10 再运算 !ok ,再进行逻辑与的运算。
在Java语言里,操作符约有几十种,想要记住它们的优先级顺序是不太容易的。但是大家可以放心的是,我们并不需要强记这些优先级,而只是需要知道几种常用的操作符的优先级就足够了。
提示:在搞不清优先级顺序的时候,请使用小括号来显示指定顺序。
3.7 类型转换操作符
在整型与浮点型之间,允许类型转换。例如,
double a = 12.77;
int b = (int) a;
System.out.println("b的值:" + b);
其中,
a 是 double 型
b 是 int 型
b = a 赋值时,要求左右两侧的类型相同。所以,把a转换在int型。也就是说,一个double类型可以转成int类型。把这对小括号称为类型转换操作符。
反过来,一个int类型也可以转换成double类型。例如,
int c = 10;
double d = (double) c;
3.7.1 类型转换时的数据损失
在double -> int 的转换过程中,数据可能发生损失。例如,
double a = 12.77;
int b = (int) a;
转换后的结果为12,即小数部分被截断。
反过来,在int -> double 的转换过程中,数据不会损失。例如,
int c = 10;
double d = (double) c;
3.7.2 显式转换与隐式转换
在类型转换的过程中,如果没有风险和数据损失,就可以把类型转换符省略。例如,
int c = 10;
double d = c; // 省略 (double) 转换符
在 d=c 的过程中,发生了隐式的类型转换,相当于
double d = (double)c ;
所以,称之为隐式转换。即自然而然的、没有任何风险的转换。
3.7.3 注意事项
(1) 小数转整数时,小数部分被截断。注意不是四舍五入!
(2) 默认其他类型是不能转换的。
例如,boolean与int是不能相互转换的,
boolean k = true;
int a = (int) k; // 错!别乱写!
3.8 其他操作符
最常使用的操作符,就是上面所列的几种。
除此之外,还有条件操作符、逗号操作符等等,并不重要,所以初学者不必过分关注。