【Java SE】运算符详解

简介: 在我们C语言深度解剖的专栏已经讲解了一些常见的运算符了,但是基本的 + - * / 没有细说,毕竟那是深度解剖,是在一定基础上更深入学习的,我们 Java 是从 0 基础讲解的,所以这里会涉及到很全面的操作符

在我们C语言深度解剖的专栏已经讲解了一些常见的运算符了,但是基本的 + - * / 没有细说,毕竟那是深度解剖,是在一定基础上更深入学习的,我们 Java 是从 0 基础讲解的,所以这里会涉及到很全面的操作符,由于 Java 很少关注底层,所以我们也不会像讲 C语言的时候那样偶尔去从汇编的角度讲解。

1、算数运算符

1.1 四则运算符

相信大家对于四则运算都不陌生啊, 毕竟谁没做过加减乘除运算,但是这里我们主要是介绍 % 运算符,它与 C语言里的有点区别我们接着往下看:

显然答案是跟我们C语言当中是一模一样的,但是这里我们需要强调一点,以上都是二元操作符,必须拥有两个操作数,不论在C还是在Java中 int / int 的结果是整数,而且是向下取整, 也就是说,会舍去小数位,尽管你是 3.9 他算出的结果仍然是 3

那么我们如果想得到小数该如何做呢?

  • 将除号两边任意一个整数乘以1.0(当两边操作数类型不同,会向类型大的提升,结果也跟着变)
  • 将除号两边任意一个整数强转成 float 或者 double
  • 直接用 double 或者 float 类型计算

注意:将他们的计算结果转化成 floatdouble 是没有用的,因为结果是取整之后的值。

接下来我们来关心我们的 % 运算:

如果是第一次看到这些结果的你们可能有些意外,我记得C语言中是不能对浮点数取模的啊,在Java中是允许这样操作的,其实上面的例子很简单,就是10以内的除法,如果你能对上面都算准确的话,那么你取模这个运算符肯定是没问题的。

注意:取模和除法时,右操作数不能为0,否则会报错! (0乘任何数都为0)

在讲C语言的时候,我们就说过,自古以来有个约定,返回值为0为正常退出,非0则为异常退出。所以在除法或者取模时,右操作数是万万不可出现 0 的!

1.2 复合运算符

这种运算符呢,常见的有:+=  -=  *=  /=  %=  >>= 等等...

他们会将操纵的结果最后赋值给左操作数。

public class TestDemo {
    public static void main(String[] args) {
        int a = 1;
        a += 1; // 相当于 a = a + 1;
        System.out.println(a); //2
        a -= 1; // 相当于 a = a - 1;
        System.out.println(a); //1
        //...... *=  /=  %= 就不一一演示了
    }
}

但是其实这里我们要有几个注意的点:

如果当我们不同类型使用符合运算符时会自动发生类型转换,不需要我们手动强制类型转换。

public class TestDemo {
    public static void main(String[] args) {
        //如果不同类型使用符合运算符会自动类型转换
        int a = 10;
        double b = 10.5;
        a += b; //等价于 -> a = (int)(a + b);
    }
}

如果当我们使用时发现运算符优先级有歧义怎么回事?比如 a += b * 3;

public class TestDemo {
    public static void main(String[] args) {
        int a = 10;
        a *= 3 + 2; //等价于 -> a = a*(3+2) 这里先把 3+2 的值算出来在乘 a 
        System.out.println(a); //50 
    }
}

只有变量才能使用符合运算符做左值,常量是不可以的,因为他不可被修改!

1.3 自增自减运算符

相信大家对于自增自减运算符并不少见,但是在Java中确实还是有跟C语言不同的地方的,我们接着往后看:

public class TestDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        b = ++a; // a = a + 1; b = a;
        System.out.println(a); //11
        b = a++; // b = a; a = a + 1;
        System.out.println(a); //12
    }
}

至于单独使用 ++a,或者a++,他们的效果是一样的,这个我就不多说,但是我们这里主要是区别前置++和后置++他们赋值的情况。

  • 前置++:先自身值增加1,然后赋值
  • 后置++:先赋值,然后自身值增加1。

但是这里又有一个小问题,如果有人闲的无聊,把a++的值再次赋值给a,会发生什么情况呢?

这里就跟C语言不一样了,C语言中如上代码算出的结果是 11,如果看过我C语言深度解剖专栏符号篇的,在那我们已经从汇编的角度去演示过他们的底层逻辑了,只不过在 Java 中我们很少去关注底层,这里我们注意一下就行,其实以后也基本不会碰到这种后置自增之后给自己赋值的代码,也不用太过于纠结,我们有个认识就行。

注意:常量不能使用前置或后置++运算符  

2、关系运算符

关系运算符这一块跟C语言基本一致,主要以下六个:==  !=   >=   <=   >   <

但是在Java中我们要区分跟C语言不同的点,前面我们强调过,Java中不存在 0为假 非0为真,说白了,以上六个关系运算符,其计算的结果为 ture 或者 false   并不是 0 或者 1。

public class TestDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a > b);  //如果a大于b,输出true 否则 输出false
        System.out.println(a < b);  //如果a小于b,输出true 否则 输出false
        System.out.println(a == b); //如果a等于b,输出true 否则 输出false
        System.out.println(a != b); //如果a不等于b,输出true 否则 输出false
        System.out.println(10 >= 15); //如果10大于或等于15,输出true 否则 输出false
        System.out.println(10 <= 15); //如果10小于或等于15,输出true 否则 输出false
    }
}

我们学编程语言,有些地方显然是不能跟数学一模一样的,就比如说:10 < a < 15,这样写是错误的,因为 10 < a 的结果是 ture 或者 false 其中任何一个结果都不能跟 15 去比较的。

注意:关系运算符两边可以出现常量

3、逻辑运算符

3.1 逻辑 && 和 逻辑 | |

逻辑运算符显然也是很不陌生的,但是在Java中逻辑运算符 && || 左右表达式的结果必须是 boolean 类型,而且整个表达式的运算结果也是 boolean

例:表达式1&&表达式2,要求:表达式1表达式2的运算结果是 boolean 类型

1 && 5 -> 这个是错误的!!!

  • &&:当运算符两边表达式的结果都为 true,则整体为 true
  • | |  :当运算符两边表达式有一个结果为 true,则真题为 true

短路现象:

  • &&:当运算符左边表达式为,则不执行右边表达式,称为短路现象
  • | |  :当运算符左边表达式为,则不执行右边表达式,称为短路现象
  • 如果 & 和 | 按位运算符两边表达式的值也为 true 或者 flase他们也表示逻辑运算,但不支持短路!
public class TestDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println((a > 10) && (a / 0 > 2)); //这里 除数为0并不会报错,因为&&出现了短路
        System.out.println((a < 20) || (a / 0 > 2)); //这里 除数为0并不会报错,因为||出现了短路
    }
}

以上代码就是逻辑与和逻辑或出现的短路现象,我们前面学习到,除数一定不能是0,否则程序会异常,但是我们上面代码可以通过,最主要原因是他们发生短路并不会去执行运算符右边的表达式,感兴趣的可以下来试一试,如果没出现短路,程序是肯定会出现异常的。

3.2 逻辑非!

int a = 10;
        System.out.println(!(a == 10)); //取非就将 true 变为 false
        //err:System.out.println(!a); 操作数结果必须为布尔值

这个就很简单了,主要注意一点,!的右边表达式结果必须为布尔值。

4、位运算符

我们知道计算机中最小的存储单位是字节,但是数据最小的操作单位是比特位,一个字节等于八个比特位,也就是八位二进制,位运算符是针对数据二进制位按位操作的。

4.1 按位与(&)和按位或( | )

由于这一块跟C语言基本一致,所以我们就大概的过一遍即可:

  • 按位与(&):如果两个二进制位都是 1, 则结果为 1, 否则结果为 0。
  • 按位或 (|): 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1。

1 & 2:

1 的二进制补码:0000 0000 0000 0001

2 的二进制补码:0000 0000 0000 0010

------按位与结果:  0000 0000 0000 0000   -> 对应十进制:0    

1 | 2 :

1 的二进制补码:0000 0000 0000 0001

2 的二进制补码:0000 0000 0000 0010

------按位或结果:  0000 0000 0000 0011   -> 对应十进制:3      

4.2 按位异或(^)和按位取反(~)

  • 按位异或(^):如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1 。
  • 按位取反(~):将数值的二进制位取反,如果该位为 0 则转为 1, 如果该位为 1 则转为 0。

1 ^ 3 :

1 的二进制补码:0000 0000  0000 0001

3 的二进制补码:0000 0000  0000 0011

---按位异或结果:  0000 0000 . 0000 0010   -> 对应十进制:2    

5 ^ 0 :

5 的二进制补码:0000 0000 ... 0000 0101

0 的二进制补码:0000 0000 ... 0000 0000

---按位异或结果:  0000 0000 ... 0000 0101   -> 对应十进制:5  

结论:任何数异或0都等于它本身,相同的数异或结果为0

按位取反具体大家可以自己下来写一下,将补码每位都取反,然后判断符号位,在转换成对应的原码即可知道取反后的值。

5、移位运算符

Java中的移位运算符比C中多了一个,具体我们下面讲,但是跟C语言并没什么太大的区别这里我们简单提一下:

  • 左移操作符 <<:二进制位向左移动 N 位,每次移动一次时最低位补0 -> 左移相当于原数字乘2的N次方
  • 右移操作符 >>:二进制位向右移动 N 位,每次移动一次时最高位补符号位 -> 右移相当于原数字除上2的N次方
  • 无符号右移操作符 >>>:二进制位向右移动 N 位,每次移动一次时最高位补0

这里我们来看一段有意思的代码:

很明显这段代码是进行两个数的平均值的,至于为什么会是这样,大家可以结合上下文,画画图或者分析一下,也可以想这样求平均值好处是什么?锻炼独立思考的能力,我就不过多说明了。

6、条件运算符

这个也是Java中唯一一个三目操作符了,它的用法跟C语言很想,但是也是有一点点小区别,毕竟Java中是true表示真,false表示假。

用法:布尔表达式1?表达式2 : 表达式3

解释:如果表达式1的结果为true则执行表达式2,如果为false则执行表达式3

public class TestDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = a > b ? (a += 10) : (b += 10);
    }
}

注意:表达式2和表达式3最好是同类型的,除非他们可以发生隐式类型转换,整个表达式的结果不能单独存在,必须要拿变量接收或者使用。

单独存在三目操作符是错误的:a > b ? a : b;

相关文章
|
2月前
|
Java
Java运算符
Java运算符
51 12
|
3月前
|
Java 测试技术 数据处理
Java零基础教学(17):Java运算符详解
【8月更文挑战第17天】Java零基础教学篇,手把手实践教学!
69 4
|
1月前
|
算法 Java 测试技术
🌟Java 零基础 | 详解 单目运算符
【10月更文挑战第14天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
39 7
|
1月前
|
Java 测试技术 开发者
🌟Java 零基础 | 深入理解三目运算符
【10月更文挑战第13天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
24 3
|
1月前
|
Java 测试技术 开发者
🌟Java零基础-Lambda运算符详解 🌟
【10月更文挑战第12天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
23 1
|
1月前
|
Java
JAVA易错点详解(数据类型转换、字符串与运算符)
JAVA易错点详解(数据类型转换、字符串与运算符)
50 4
|
1月前
|
安全 Java 测试技术
🌟 Java 零基础 | 详解 instanceof 运算符
【10月更文挑战第1天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
33 1
|
1月前
|
存储 Java C语言
【一步一步了解Java系列】:了解Java与C语言的运算符的“大同小异”
【一步一步了解Java系列】:了解Java与C语言的运算符的“大同小异”
39 3
|
2月前
|
Oracle Java 关系型数据库
Java(TM) Platform SE binary 已停止工作”的解决方法
Java(TM) Platform SE binary 已停止工作”的解决方法
236 2
|
2月前
|
Java 测试技术 程序员
Java零基础(23) - Java赋值运算符,了解一下!
【9月更文挑战第2天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
62 11
下一篇
无影云桌面