Java 算术运算符
Java 算术运算符
运算符介绍
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
常用的有
优先级
算术运算符
| 运算符 | 运算 | 范例 | 结果 |
|---|---|---|---|
| + | 正号 | +1 | 1 |
| - | 负号 | -2 | -2 |
| + | 加 | 1 + 2 | 3 |
| - | 减 | 9 - 5 | 4 |
| * | 乘 | 1 * 5 | 5 |
| / | 除 | 12 / 2 | 6 |
| % | 取模(取余) | 70 % 9 | 7 |
| ++前 | 前自增:先运算(+1)后取值(赋值) | a = 7; b = ++a; |
8 |
| 后++ | 后自增:先取值(赋值)后运算(+1) | a = 9; b = a++ |
9 |
| --前 | 前自减:先运算(-1)后取值(赋值) | a = 11; b = --a |
10 |
| 后-- | 后自减:先取值(赋值)后运算(-1) | a = 11; b = a-- |
11 |
| + | 字符串相加 | "Hello" + "Java"; |
HelloJava |
除法应用:
以上加减乘除的使用和数学是一样的,使用除法时需要注意的是,前面数据类型有提过,自动提升原则: 表达式结果的类型自动提升为 操作中最大的类型。如果不注意,会出现计算结果不准确的情况。
例如:
System.out.println(5 / 2);
在数学的计算中 以上 5 / 2 只会得到结果 2.5 而在 Java 中得到的结果却是2。
因为 Java 在运算中,会先把 运算语句中的所有值提升到该语句中最大的那个类型,然后再进行计算,因为 5 / 2 Java 的整数类型默认常量是 int 所以这里的 5 和 2 都是int类型,Java在这里并不会将类型自动转换成double类型,而是选择直接将小数点及其后面的数值抹去。所以结果为2。
要避免出现这种情况,只要让运算语句中的最大类型变为double类型就可以
例如 5.0 / 2; 这样语句中的最大类型就是 double了,根据 Java的自动提升原则。这样得出的结果也会是 double 类型。所以结果2.5。
注意:
- 以上例子直接将运算结果赋值给
double类型的变量,根据先运算,后赋值原则,结果依旧会是2.0,因为运算结果是int类型,相当于double a = 2。 - ⭐自增、自减 会进行类型转换 如:
byte num = 1; ++num;等价于num = (byte)(num + 1);类型转换值会将1的类型变成与变量一样的类型。
取模说明:
- 取模即取余 本质就是这个公式 :
a - a / b * b其中a / b舍余再进行后面的运算。
自增说明:
自增或自减就是给变量自身 +1 或 -1
自增与自减的原理一样,只不过一个是加一个是减,以下一律用自增说明
前自增与后自增在独立使用 (只自增,不涉及赋值/取值) 的情况下没有区别
在作为表达式使用时自增就相当于一条语句干了两条语句的活。(也就是简写)
如:
-
a = 1; /* 这句语句相当于 a = a + 1; b = a; */ b = ++a;
前自增与后自增在作为表达式使用时的区别就在于先 +1 还是先 赋值
如上面的例子就是 先自增最后 a 和 b 的结果分别是 2 和 2。
而后自增:
-
a = 1; /* 这句语句相当于 b = a; a = a + 1; */ b = a++; -
a和b的结果分别是2和1。
上面说到的全部是自增前或自增后赋给其他变量,那么自增前,着自增后赋值给自己呢,一个 Java 烂大街的例子:
// 例1:
int a = 1;
a = a++;
// 例2:
int a = 1;
a = ++a;
看结果前,先大致了解一下自增前后赋值,Java 都干了什么事,拿例1来举例:
a = a++ : Java 看到是是先赋值后自增,会先创建一个临时变量这里假设变量名为 temp ,然后把 a 赋值给 temp ,再执行 i = i + 1 最后再把 temp 赋给变量 i。
大致过程就是:
int a = 1;
a = a++;
// 发现是赋值给自身后,Java内部创建临时变量 temp 并将 a 赋给 temp
int temp;
temp = a; // 此时temp的值是 1
// 然后执行自增
a = a + 1; // 此时 a 的值是 2
// 自增完成后再把 临时变量 temp 赋回给 变量 a
a = temp; // 此时 a 的值是 temp 的值
//结果就是:a = 1
而前自增和上面的原理基本一样:
int a = 1;
a = ++a;
// 过程简述
a = a + 1; // result : 2
int temp = a; // result : 2
a = temp; // result : 2
// 结果是: 2
关系运算符
关系运算符返回的结果只有两个 true 和 flase 也就是 布尔类型
关系运算符有如下几个:
| 运算符 | 运算 | 范例 | 结果 |
|---|---|---|---|
| == | 相等于 | 8 == 7 | false |
| != | 不等于 | 8 != 7 | true |
| < | 小于 | 8 < 7 | false |
| > | 大于 | 8 > 7 | true |
| <= | 小于或等于 | 8 <= 7 | false |
| >= | 大于或等于 | 8 >= 7 | true |
| instanceof | 检查是否是类的对象 | "Java" instanceof String |
true |
逻辑运算符
用于连接多个条件(多个关系表达式), 返回的结果也是一个 boolean 类型的值
先了解 与 、或、非、异或(我学到这里因为没先了解这些概念直接看讲师用代码讲解把我讲蒙了)
与只有当两个条件同时为true才返回true,否则返回false或两个条件只要有一个为true就会返回true,否则返回false非(也叫取反) 将条件返回的true变为false异或只要两个条件的结果不一致,就会返回true,否则返回false- 学过
Python的可以这样理解与=and,或=or,非=not
| 运算符 | 名称 | 描述 |
|---|---|---|
| & | 逻辑与 | 两个条件同时满足返回 true,否则false |
| | | 逻辑或 | 只要有一个条件满足返回true,否则false |
| ! | 非 | 将逻辑结果取反 |
| ^ | 异或 | 只要两个结果不一致就返回true 否则 false |
| && | 短路与 | 跟&一样,但只要第一个条件不为true就直接返回false |
| || | 短路或 | 跟|一样,但只要第一个条件为true就直接返回true |
这里先不理会&& 和 ||
代码实例:
public class LogicOperator {
public static void main (String[] args) {
// 逻辑与 的代码应用
// 只有当两个条件同时为 true 才返回 true
System.out.println(1 < 2 & 2 < 3); // 结果:true
System.out.println(1 < 2 & 2 > 3); // 结果:false
System.out.println(1 > 2 & 2 < 3); // 结果:false
System.out.println(1 > 2 & 2 > 3); // 结果:false
// 逻辑或的代码应用
// 两个条件只要有一个为 true 就会返回 true
System.out.println(1 < 2 | 2 < 3); // 结果:true
System.out.println(1 < 2 | 2 > 3); // 结果:true
System.out.println(1 > 2 | 2 < 3); // 结果:true
System.out.println(1 > 2 | 2 > 3); // 结果:false
// 非的代码应用
// 将逻辑结果取反
System.out.println(!(1 < 2)); // 结果:false
System.out.println(!(1 > 2)); // 结果:true
// 异或的代码应用
// 只要两个结果不一致就返回 true
System.out.println(1 < 2 ^ 2 < 3); // 结果:false
System.out.println(1 < 2 ^ 2 > 3); // 结果:true
System.out.println(1 > 2 ^ 2 < 3); // 结果:true
System.out.println(1 > 2 ^ 2 > 3); // 结果:false
}
}
接下来说说,短路与 和 短路或 ,他们和逻辑与 和 逻辑或 的功能是一样的,但只要提前达到他们成立的条件,就会直接返回结果。例如:
1 > 2 && 2 < 3 其中 1 > 2 对于短路与来说这个条件不成立,后面的 2 < 3就不会进行判断,也就是不会执行,因为不管 2 < 3 的结果是 true 还是 false 对于 短路与 来说已经不重要了,只要第一个条件是 false 那么这整条逻辑判断语句的结果只会是 false。
对于短路或来说道理也类似
1 < 2 || 2 > 3 其中 1 < 2 对于 短路或 来说,1 < 2 这个条件已经成立,后面的条件结果也不会进行判断,因为 或 的成立条件是只要有一个为 true 则返回 true。既然条件已经成立就无需继续后面的逻辑判断。
在开发中应该尽可能的使用 && 短路与 和 || 短路或,因为他们的效率更高。
而 & 和 | 不管你条件是否提前成立,都会将整条逻辑判断语句执行完后才返回结果。
给个简单的例子看一下就知道了:
// 与
int i = 1;
System.out.println(1 > 2 & ++i > 2);
System.out.println("i = " + i);
/**
* 结果:
* false
* i = 2
*/
// 短路与和逻辑与的区别
int a = 1;
System.out.println(1 > 2 & ++a > 2);
System.out.println("a = " + a);
/**
* 结果:
* false
* a = 1
*/
可以看到 & 语句里执行了 后面 ++i > 2 的判断,而 && 并没有执行 ++a > 2。
不要小看这点开销,一个程序里加入有几百 或者 几千 几万个这样的判断呢,如果后面执行的不是 自增,而是对计算机开销更大的语句呢 ,如果使用了 短路或 或者 短路与 就能省些这些空间和时间,对程序来说就是运行效率更高。
赋值运算符
赋值运算符就是将某个运算后的值,赋给指定变量
| 运算符 | 运算 | 范例 | 结果 |
|---|---|---|---|
| = | 赋值 | int num = 1 |
num = 1 |
| += | var = var + number | num = num + 1 |
num = 2 |
| -= | var = var - number | num = num - 1 |
num = 0 |
| *= | var = var * number | num = num * 1 |
num = 1 |
| /= | var = var / number | num = num / 1 |
num = 1 |
+=、-=、*=、/= 都叫复合运算符
赋值运算符的特点:
- 运算顺序先执行
=右边的语句int num = a + b + c,然后再把结果赋给=左边的变量。 - 赋值运算符的左边只能是变量,右边可以是
变量、表达式、常量值。例:int num = 1;int num2 = 1 + 1 - 2;int num3 = var; - 复合赋值运算符相当于赋值运算符 + 表达式的简写,如:
int a /= b;等价于int a = a / b; - ⭐复合运算符会对
=右边的变量进行类型强制转换,转换成与接收变量相同的类型。例 假设byte num = 127;number += 1;这样num就变成了-128也就是溢出了。
三元运算符
基本语法 条件表达式(true或flase) ? 表达式(true要执行的语句) : 表达式(false要执行的语句);
代码例子:
int a = 1;
int b = 2;
int result = a > b ? a++ : b++;
例子解读:
- 如果
a > b为true则执行:左手边的表达式。如果为false则执行:右手边的表达式。 - 然后再将 表达式的结果赋给
=左手边的变量。 - 上面的例子最后
result的接收的值是2因为a > b是false所以执行b++而b++是后++ ,所以先把b赋给result再给b+ 1。
三元运算符可以看成是简单的 if 判断语句的简写,上面的例子等价于
// 虽然还没学 if 但是这么简单的代码应该是能看懂的。
int a = 1;
int b = 2;
if (a > b) {
a++;
}else{
b++;
}
注意:
: 左手边和右手边的表达式必须是可以给接收变量赋值的类型 例如 int result = a > b ? 1.1 : 2.2;这样就会报错,因为无法将 double 类型的数据赋给int 类型的变量。
运算符优先级
运算符优先级由高到低,从上往下看。
| 运算符 | 类别 |
|---|---|
. () {} ; , |
|
++ -- ~ !(data type) |
单目运算符 |
* / % |
算术运算符 |
+ - |
算术运算符 |
<< >> >>> |
位移运算符 |
> < >= <= instanceof |
比较运算符 |
== != |
单目运算符 |
& |
逻辑运算符 |
^ |
逻辑运算符 |
| |
逻辑运算符 |
&& |
逻辑运算符 |
|| |
逻辑运算符 |
? : |
三元运算符 |
= *= /= %= |
赋值运算符 |
+= -= <<= >>= |
赋值运算符 |
>>>= &= ^= |= |
赋值运算符 |

浙公网安备 33010602011771号