【Java】Java的各种运算符

228 阅读7分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。

前言

在上班摸鱼的时候,就想着来数一数 Java 中有多少运算符,意外发现了我遗漏的 Java 运算符,于是我决定写这篇文章来归类一下所有 Java 运算符。

Java 运算符主要有以下几种分类:

  1. 关系运算符(>,<,==,!=,>=,<=)
  2. 位运算符(&,|,^,~,<<,>>,>>>)
  3. 算数运算符(+,++,-,--,*,/,%)
  4. 逻辑运算符(&&,&,||,|,!)
  5. 赋值运算符(=,+=...)
  6. 其他运算符(?:,.)

关系运算符

关系运算符(>,<,==,!=,>=,<=)是用来比对两个元素值(整型或者字符)的大小,根据比较返回一个布尔类型,主要都是两元运算符

通常这些元素只能是Java 基础类型,不包括布尔(返回值就是布尔),字符是需要参照 ASCII 编码或者 Unicode 编码,把字符转成数值然后参与比较,其他的类型直接参与比较。

不同的数据类型之间会存在数据类型之间的转换,这里主要是比较数值,不考虑精度的丢失,所以后面再展开讲解。

这些符号的逻辑是怎么样的,怎么判定返回结果,相信大家看一看就会了。

符号含义
当在符号前面的数(下文简称前者)大于符号后面的数(下文简称后者)时,返回结果为 true,反之为 false
<当前者小于后者时,返回结果为 true,反之为 false
==当前者等于后者时,返回结果为 true,反之为 false
!=当前者不等于后者时,返回结果为 true,反之为 false
>=当前者大于或者等于后者时,返回结果为 true,反之为 false
<=当前者小于或者等于后者时,返回结果为 true,反之为 false

以下为运行代码:

System.out.println(1<2); //true
System.out.println(1<=2); //true
System.out.println(1>2); //false
System.out.println(1>=2); //false
System.out.println(1==2); //false
System.out.println(1!=2); //true
System.out.println('1'<'2'); //true
System.out.println(3.14F<'2'); //true
System.out.println(3.14F<'2'); //true
System.out.println(3.14F<4L); //true

位运算符

位运算符(&,|,^,~,<<,>>,>>>)是对比特位进行操作的一种运算符,可以使用该运算符的数据类型为整型或字符,返回的数据类型是整型,基本都是两元运算符

在 Java 中,整型可以使用 2、8、10、16 进制表示。

  • 二进制:以 0B 或者 0b 开头。
  • 八进制:以 0 开头。
  • 十进制:不能以 0 开头,就平常的数字。
  • 十六进制:以 0X 或者 0x 开头。

我们再人工运算位运算时,得把十进制的数字用二进制表示出来,然后一位一位数去对比。

(7)10 = (111)2

符号含义
&与运算。两个比特位同为 1,结果为 1,否则为 0。
|或运算。两个比特位任意一个为 1,结果为 1,否则为 0。
异或运算。两个比特位相同时,结果为 1,否则为 0。
~取反运算。这是一个一元运算符,反转比特位,1 变为 0,0变为 1。
<<左移。把二进制数往左移动,每移动一位,最右边的一位补 0,该操作符右边的数是要移动的位数。
>>右移。把二进制数往右移动,每移动一位,最左边的一位是啥就补啥,该操作符右边的数是要移动的位数。
>>>无符号右移。这个跟右移一样,只不过最左边一位补的是 0。
int a = 0B0111;
int b = 0B1001;
System.out.println(Integer.toBinaryString(a&b));
System.out.println(Integer.toBinaryString(a|b));
System.out.println(Integer.toBinaryString(a^b));
System.out.println(Integer.toBinaryString(a<<2));
System.out.println(Integer.toBinaryString(b>>2));
System.out.println(Integer.toBinaryString(b>>>2));
/**
 1
 1111
 1110
 11100
 10
 10
 */

算数运算符

算数运算符(+,++,-,--,*,/,%)主要是对整型进行运算,也可以运算字符,返回的是一个整型。

加减乘除,小学算术了。

符号含义
+加法、求正。当 + 在一个数前面时,表示获取这个数的正数,然而实际上没啥作用。
-减法、求负。当 - 在一个数前面时,表示获取这个数的负数,就是正数变成负数,负数变成正数。
++自增。 a++等同于a = a + 1;
--自减。a--等同于a = a -1;
*乘法。
/除法。
%求余数。a % b = a - (a/b)b
int c = 1;
int d = 2;

System.out.println(c+d);
System.out.println(c-d);
System.out.println(3*2);
System.out.println(10/2);
System.out.println(10%2);
System.out.println(c++);
// 打印后 c 已经自增了
System.out.println(++c);
System.out.println(c--);
// 打印完后 c 已经自减
System.out.println(--c);

/**
 3
 -1
 6
 5
 0
 1
 3
 3
 1
 */

这里还会涉及到类型转换的问题,这里贴一个Java核心技术卷的图

image.png

在不同的类型数据进行运算时,会按照类型的等级,把等级低的数据转换成高的再开始计算。

我在这里简单总结一下数据类型的等级:byte > short / char > int > long > float > double。更加详细地可以参考上图,实线代表没有精度丢失,虚线会丢失精度。

逻辑运算符

逻辑运算符(&&,&,||,|,!)是对布尔值进行运算,返回一个布尔值。

看到 &、|、^,你可能会说这不是位运算符吗?怎么会归类到逻辑运算符?

这三个符号确实也可以对布尔值进行运算,要知道在 c/c++ 中,true 的值为 1,false 的值为 0,只不过在 java 中 true 是 true,false 是 false,但仍然支持使用位运算符来运算布尔值。

与 &&、|| 不同的是,&、| 不存在断位

符号含义
&逻辑与。同位运算符的 & 类似,符号两边的都是 true ,结果才为 true,否则为 false。
逻辑或。同位运算符的类似,符号两边任意一个是 true ,结果就为 true,否则为 false。
逻辑异或。同位运算符的 ^ 类似,当符号两边不同时,也就是一个为 true,另一个为 false 时,结果才为 true。
逻辑非。同位运算符的 ~ 类似,把 true 变为 false,把 false 变为 true。
&&断位逻辑与。这也是一个逻辑与,但它还会断位,运算时从左往右,当遇到一个 false 时,就会返回结果为 false,并且不继续往下计算
断位逻辑或。这也是一个逻辑或,同样的它也会断位,运算时从左往右,当遇到一个 true 时,就会返回结果为 true,并且不继续往下计算。
System.out.println(!true);
System.out.println(false^true);
System.out.println(false^false);
int i = 0;
System.out.println(i == 0 | i++ != 0);
//会执行后面的 i++
System.out.println("i ="+i);
i = 0;
System.out.println(i == 0 || i++ != 0);
System.out.println("i ="+i);

i = 0;
System.out.println(i != 0 & i++ == 0);
//会执行后面的 i++
System.out.println("i ="+i);
i = 0;
System.out.println(i != 0 && i++ == 0);
System.out.println("i ="+i);
/**
false
true
false
true
i =1
true
i =0
false
i =1
false
i =0
*/

赋值运算符

赋值运算符(=,+=...)运算符号右边的表达式或者方法,把结果赋值给左边的变量。

符号含义
=把符号右边运算的结果(以下简称结果)赋值给符号左边的变量(以下简称变量)。
+=变量加上结果,再赋值给变量, a+=n;等同于a = a + n;
-=变量减结果,再赋值给变量, a-=n;等同于a = a - n;
/=变量除以结果,再赋值给变量, a/=n;等同于a = a / n;
*=变量乘结果,再赋值给变量, a*=n;等同于a = a * n;
%=变量取模于结果,再赋值给变量, a%=n;等同于a = a % n;
int a = 1;
a+=1;
System.out.println(a);// 2
int b = 1;
b-=1;
System.out.println(b);// 0
int c = 1;
c*=10;
System.out.println(c);// 10
int d = 10;
d/=5;
System.out.println(d);// 2
int e = 10;
e%=3;
System.out.println(e);// 1

其他运算符

其他运算符(?:,.)

三目运算符

Java 中仅有一个三目运算符(三元运算符),那就是?:,这个运算符的作用是简化if,可以让我们的代码变得更加简洁。

用法:

a = A?B:C

A 可以是一个逻辑表达式或者只是单纯的布尔值。

当 A == true 时,返回结果 B。

当 A == false 时,返回结果 C。

相当于

 if(A){
     a = B;
 }else{
     a = C;
 }

.

.,一个点。在 Java 中.是对象用来连接属性或者方法的符号。

例如如下操作

 s.length;
 s.toString;

这里会涉及到访问修饰符,就是决定某个属性或者方法是否能够被访问的修饰符。

有以下四种:

  1. private。私有,仅在本类内部可以见,修饰对象不能是外部类。
  2. default。默认,也就是什么都不写,修饰对象可以是类、接口、变量、方法。
  3. protected。保护,包外不可见(情况复杂,后面详细解释),修饰对象可以是类、变量、方法。
  4. public。开放,全部地方都可见,修饰对象可以是类、接口、变量、方法。

整理为一个表格如下:

修饰符本类(访问)同包的其他类(访问)其他包(访问)同包(是否可被继承)其他包(是否可被继承)
privateYNNNN
defaultYYNYN
protectedYYNYY
publicYYYYY

这里稍微解释一下,最简单的两个修饰符就是 private 和 public,前者仅有本类内部可以访问,后者所有类都可以访问,这个很简单。

而 default 和 protected 是在同一个包内部和其他包的访问权限有所不同。

简单记一下 protected 和 default。

  • 就访问权限而言,在同一个包内就是 public,包内的所有类都可以访问,在其他包就是 private,其他包的所有类都不能访问。
  • 但是在继承操作上,protected 和 public 一样,而 default 仅只有包内能够被继承。