Java 程序是由许多语句组成的,而语句的基本操作单位是表达式与运算符。运算符就是数学中的运算符号,如 +
、-
、*
、 /
等等。
Java 中提供了许多的运算符,这些运算除了可以处理一般的数学运算外,还可以处理逻辑运算、位运算。根据使用的作用不同,运算符可以分为赋值运算符、算数运算符、关系运算符、逻辑运算符、条件运算符和括号运算符等等。
想要为各种不同的数据类型的变量赋值时,就必须要用赋值运算符 =
,在 Java 中赋值运算符就只有一个,它是 Java 语言中不可或缺的。
下列为赋值运算符成员:
赋值运算符号 | 描述 |
---|---|
= | 赋值 |
在这里 =
不是 “等于” 的意思,而是 “赋值” 的意思。赋值语句如下:
int num = 20 ;
一元运算符就只需要一个操作数。下面的语句就表示由一元运算符与一个操作数组成:
+3; //表示正数3
-4; //表示负数4
!a; //表示 a 的 NOT 运算,如果 a 为 0,则 !a 为 1,如果 a 不为 0,则 !a 为 0
下面是一元运算符成员:
序号 | 一元运算符 | 描述 |
---|---|---|
1 | + | 正号 |
2 | - | 负号 |
3 | ! | NOT,否 |
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
boolean b = false;
int x = 10 ;
int y = -30;
System.out.println("b = " + b + ",!b = " + !b);
System.out.println("x = " + x + ",-x = " + -x);
System.out.println("y = " + y + ",+y = " + +y);
}
}
运算效果如下:
从上面可以看出,b 的初始值为 false,经过 !
运算,b 值变为了 true。
算数运算符在数学中经常用到,它的成员列表为:
序号 | 算数运算符 | 描述 |
---|---|---|
1 | + | 加法 |
2 | - | 减法 |
3 | * | 乘法 |
4 | / | 除法 |
5 | % | 取余数 |
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
int num1 = 20;
int num2 = 5;
System.out.println("num1 + num2 = " + (num1 + num2));
System.out.println("num1 * num2 = " + (num1 * num2));
System.out.println("num1 - num2 =" + (num1 - num2));
System.out.println("num1 / num2 = " + (num1 / num2));
System.out.println("num1 % num2 = " + (num1 % num2));
}
}
运算结果如下:
从运行结果可以看出和我们在数学中的加减乘除的效果是一样的。
使用关系运算符得出的结果是 boolean 类型的。它的表示方式和数学中差不多,但是由于 =
号是赋值语句,为了区分所以使用了 ==
。而不等于形式比较特别,所以就用了 !=
来表示。 通常在条件判断是时候用到。它的成员列表为:
序号 | 关系运算符 | 描述 |
---|---|---|
1 | > | 大于 |
2 | < | 小于 |
3 | >= | 大于等于 |
4 | <= | 小于等于 |
5 | == | 等于 |
6 | != | 不等于 |
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
System.out.println("2 > 1 : " + (2 > 1));
System.out.println("2 < 1 : " + (2 < 1));
System.out.println("2 >= 1 : " + (2 >= 1));
System.out.println("2 <= 1 : " + (2 <= 1));
System.out.println("2 == 1 : " + (2 == 1));
System.out.println("2 != 1 : " + (2 != 1));
}
}
运行结果如下:
自增自减运算符是对一个数据类型的数据进行操作,自增和自减会对被操作的数据加 1 或者 减 1。它的成员列表如下:
序号 | 自增与自减运算符 | 描述 |
---|---|---|
1 | ++ | 自增,变量值加1 |
2 | – | 自减,变量值减1 |
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
int num1 = 5;
int num2 = 6;
int num3 = 7;
int num4 = 8;
// 自增自减运算符在后面
System.out.println("num1 = " + num1);
System.out.println("num1++ = " + (num1++) +"; num1 = " + num1);
System.out.println("num2 = " + num2);
System.out.println("num2-- = " + (num2--) +"; num2 = " + num2);
//自增自减运算符在前面
System.out.println("num3 = " + num3);
System.out.println("++num3 = " + (++num3) +"; num3 = " + num3);
System.out.println("num4 = " + num4);
System.out.println("--num4 = " + (--num4) +"; num4 = " + num4);
}
}
运行效果如下:
从运行结果中,我们可以看到,数据最终得到了我们想要的值,但是自增运算符放在前面和后面结果是有差异的。++
和 --
相当于给之前的值 +1
或者 -1
。
++
放前面表示先进行 +1
操作,再进行赋值操作,++
放在后面表示先进行赋值操作,再进行 +1
操作。所以我们看到结果中,会存在输出的值和之前的值相同的场景,但是再将原先的变量输出,结果就变成了预期的结果。
逻辑运算符可以链接多个逻辑运算,逻辑运算符的成员列表如下:
序号 | 逻辑运算符 | 描述 |
---|---|---|
1 | & | AND,与 |
2 | && | 短路与 |
3 | | | OR,或 |
4 | || | 短路或 |
在使用逻辑运算符 &&
时,如果在两边的运算都是真,那么就返回真,如果有一个为假就返回假,在 ||
中,判断条件如果有一个为真,那么结果就为真,如果全部是假,那么结果才为假。
既然已经有了与和或了,那么为什么还需要短路与和短路或呢?因为 &&
和 ||
是需要将所有的判断条件都执行的,而短路与在执行过程中,如果遇到一个假,那么它后面的判断逻辑就不会继续执行,直接返回假。短路或如果在判断时候遇到一个真,那么就返回真,不会继续执行后面的判断逻辑。
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
boolean flag1 = true;
boolean flag2 = false;
System.out.println("true && false = " + (flag1 && flag2) );
System.out.println("true || false = " + (flag1 || flag2) );
System.out.println("true & false = " + (flag1 & flag2) );
System.out.println("true | false = " + (flag1 | flag2) );
System.out.println("true && true = " + (flag1 && flag1) );
System.out.println("false || false = " + (flag2 || flag2) );
}
}
运行结果如下:
括号运算符是 Java 中最常用的运算符,它是优先级比较高的运算符,一般被括号包扩的运算符会首先执行。括号运算符的成员列表如下:
序号 | 括号运算符 | 描述 |
---|---|---|
1 | () | 小括号 |
2 | [] | 大括号 |
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
int num1 = 10;
int num2 = 5;
System.out.println("num2 + num1 / num2 = " + (num2 + num1 / num2));
System.out.println("(num2 + num1) / num2 = " + ((num2 + num1) / num2));
}
}
运行结果如下;
我们可以看到一开始的时候,是按照数学里面的计算逻辑,先乘除后加减,然后用括号包起来后,顺序就先执行括号里面的。
在 Java 中位运算符主要针对二进制,它包括了 与
、非
、或
、异或
。位运算符的成员列表如下:
序号 | 位运算符 | 描述 |
---|---|---|
1 | & | 与 |
2 | ^ | 异或 |
3 | | | 或 |
4 | ~ | 非 |
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
int num1 = 10; // 二进制 1010
int num2 = 5; // 二进制 0101
System.out.println("num2 & num2 = " + (num1 & num2)); //0000
System.out.println("num1 | num2 = " + (num1 | num2)); //1111
System.out.println("~num1 = " + (~num1));
System.out.println("num1 ^ num2 = " + (num1 ^ num2)); //1111
}
}
运行结果如下:
我们可以看到除了 ~
的运算超过我们的预期,其他的操作都是在预期之内。
操作符 | 描述 |
---|---|
& | 位数都是 1 返回 1,有 0 返回 0 。 |
| | 遇到 1 返回 1,都是 0 返回 0。 |
^ | 如果相同则为 0 ,不同则为 1。 |
~ | 取反运算符。 |
~ 在 Java 中,所有数据的表示方法都是以补码的形式表示,如果没有特殊说明,Java 中的数据类型默认是 int, int 数据类型的长度是 8 位,一位是四个字节,就是 32 字节,32 bit。10 的二进制 1010。补码后为:
00000000 00000000 00000000 00001010
取反为:
11111111 11111111 11111111 11110101
因为高位是 1 ,所以原码为负数,负数的补码是其绝对值的原码取反,末尾再加 1。因此,我们可将这个二进制数的补码进行还原: 首先,末尾减 1 得反码:11111111 11111111 11111111 11110100。
其次,将各位取反得原码:00000000 00000000 00000000 00001011,得到的二进制为 11。再对其取反得 -11。
在上一节中我们详细表述了各个 运算符,每个运算符都是有优先级的。下面列出各个操作符的优先级,数字越小表示优先级越高。
优先级 | 运算符 | 类 | 组合性 |
---|---|---|---|
1 | () | 括号运算符 | 由左至右 |
1 | [] | 方括号运算符 | 由左至右 |
2 | !、+(正号)、-(负号) | 一元运算符 | 由右至左 |
2 | ~ | 位逻辑运算符 | 由右至左 |
2 | ++、– | 自增与自减运算符 | 由右至左 |
3 | *、/、% | 算数运算符 | 由左至右 |
4 | +、- | 算数运算符 | 由左至右 |
5 | <<、>> | 位左移、右移运算符 | 由左至右 |
6 | >、>=、<、<= | 关系运算符 | 由左至右 |
7 | ==、!= | 关系运算符 | 由左至右 |
8 | &(位运算符 AND) | 位逻辑运算符 | 由左至右 |
9 | ^(位运算符 XOR) | 位逻辑运算符 | 由左至右 |
10 | |(位运算符号 OR) | 位逻辑运算符 | 由左至右 |
11 | && | 逻辑运算符 | 由左至右 |
12 | || | 逻辑运算符 | 由左至右 |
13 | ?: | 三目运算符 | 由右至左 |
我们可以用下面的例子,计算 a++ - --b * ++a / b-- >> 2 % a--;
的值。
package com.haicoder.net.basic;
public class OperatorTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
int a = 5;
int b = 4;
int c = a++ - --b * ++a / b-- >> 2 % a--;
System.out.println("第一步 :" + (6 - 3 * 7/2 >> 2 % 6)); //第一步计算 ++ 和 --
System.out.println("第二步: " + (6 - 10 >> 2)); //计算 * / %
System.out.println("第三步:" + (-4 >> 2)); //计算 -
System.out.println("最终结果: " + c);
}
}
运行结果如下:
按照表格中的优先级,我们先计算了 ++
和 --
操作符,然后根据算数法则,计算了 *
、 /
、 %
,然后计算了 -
。最终计算 >>
。得到结果。