前言

在前一篇文章中,壹哥给大家讲解了Java数据类型之间的转换,包括自动类型转换、强制类型转换、隐含的强制类型转换等问题。且在上一篇文章中,我还简单地给大家提到了Java的类型提升。在类型提升的案例中,我们涉及到了Java里的运算符。有的小伙伴会很好奇,Java里的运算符都有哪些呢?加减乘除这些符号都有吗?实际上,Java中的运算符不仅仅只有加减乘除哦,还有很多其他的运算符。那么今天壹哥就用一篇专门的文章,给大家讲解运算符相关的知识。

------------------------------前戏已做完,精彩即开始----------------------------

全文大约【6400】字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......

一、运算符简介

1. 概述

电脑的大名之所以被称为”计算机“,是因为它最基本、最起初的作用就是进行数学运算。为了实现计算功能,Java为我们提供了多种运算符用于各种计算,比如算术运算符(+ - * /)、 关系运算符(< > ==)、逻辑运算符、位运算符、条件运算符等等。

2. 分类

如果我们把运算符按照功能来分,可以分为算术运算符、关系运算符、赋值运算符、逻辑运算符、位运算符、三目运算符、逗号运算符等各种运算符。

如果按照操作数的数目来分,可以把这些运算符分为单目运算符、双目运算符和三目运算符,分别对应于1个、2个、3个操作数。

3. 运算符的目

我们把运算符能够连接操作数的个数,称为运算符的目,Java中运算符的目有三种:

单目运算符:只能连接一个操作数,如“+ +”、”--”;

双目运算符:可以连接两个操作数,Java语言中多数运算符都属于双目运算符,如“+、-、*”等;

三目运算符:可以连接三个操作数,Java语言中只有一个三目运算符,即条件运算符”? :“。

4. 运算符的优先级

运算符的优先级是指在表达式中出现多个不同的运算符,在进行计算时运算符执行的先后次序。比如算术运算符中,乘除运算符的优先级高于加减运算符的优先级。在Java语言中,不同的运算符具有不同的优先级,我们在开发时要优先处理优先级高的运算符。参考下图:

这么多的优先级规则,你很难记得住,其实你也不必记忆,我们在使用时直接加括号就可以了,和数学里的规则一样。

5. 运算符的结合方向

运算符的结合方向又称为结合性,是指当一个操作数连接两个相同优先级的运算符时,会按运算符所规定的结合方向进行处理。Java中各运算符的结合性分为两种,分别为左结合性(自左向右)和右结合性(自右向左)。比如常见的+、-、*、/等运算就是自左向右,而Java里的=赋值运算,则是从右向左。

在Java中,所有的数学运算都是从左向右进行运算的,其他的大部分运算也是遵守从左向右的规则。但一元运算符,赋值运算符和三目运算符例外,他们是从右向左进行运算的。

了解完这些基本的知识之后,接下来壹哥就通过一些代码案例,分别给大家讲解一下这几种运算符的用法。

二、算术运算符

1. 概念

算术运算符与我们在数学中学习的计算符号一样,主要用在数学表达式中,常见的算术运算符有:

+ - * / % ++ --

这几个符号的功能如下表所示:

2. 案例

壹哥在这里设计了如下案例,大家要跟着练习哦。

2.1 基本运算

public class TypeDemo04 {

    public static void main(String[] args) {
//算术运算符
//注意类型提升:两个数计算,结果取决于范围大的数!比如两个int计算,结果还是int;
//而int与浮点数进行计算,则结果为浮点数,即结果变成更大范围的类型,这就是类型提升!
int a = 10;
//double b = 20.0;
int b=20; //+号的第1个作用:数学计算
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
//两个int类型相除或相乘,结果依然是int,不会出现小数哦!而且会向下取整。
System.out.println(a/b);
System.out.println(a%b);
//除法和取模运算中,右操作数不能取0
System.out.println(a/0);
} }

我们要特别注意,整数由于存在范围的限制,如果计算结果超出了范围,就会产生溢出。而溢出不会出错,但会得到一个奇怪的结果。

2.2 除零算术异常

另外壹哥还要提醒大家一下,在Java中的除法和取模运算,和数学中的要求一样,是不能做除零操作的,否则在运行时会产生异常哦!这里会产生java.lang.ArithmeticException: / by zero的异常。

2.3 类型提升(重点)

我们在进行数值计算时,要注意类型提升的问题。当算术表达式中包含不同的基本类型值时,整个算术表达式的类型会进行自动提升。基本的提升规则为:

为了计算方便,Java会将小于4个字节的类型,在计算时将其隐形提升到int类型。所以byte类型、short类型和char类型会被提升为int类型,不管是否有其他类型参与运算。也就是说,整个表达式的类型会自动提升到与表达式中最高等级的操作数相同的类型。所以两个数值进行计算,结果取决于范围更大的那个数!比如两个int计算,结果是int。而int与浮点数进行计算,则结果为浮点数,即结果变成更大范围的类型,这就是类型提升!

提升等级顺序为:

byte、short、char --> int --> long --> float --> double

所以由于类型提升的原因,我们在开发时很少使用byte或者short来定义整数。也很少会使用char类型定

义字符,而是使用字符串类型,更不会使用char类型做算术运算。

2.4 +号的两个作用

Java中的+号有2个功能,一是可以进行加法操作,二是可以进行字符串拼接。尤其是在进行字符串拼接时,要考虑自左向右的结合性。当字符串在前,数字在后,执行字符串拼接操作;当数字在前,字符串字后,先计算出结果,再进行字符串的拼接。

public class TypeDemo04 {

    public static void main(String[] args) {
//+号的第2个作用:字符串拼接,自左向右的结合性,字符串在前,数字在后,执行字符串拼接操作。
System.out.println("hello"+1+2); //hello12
//自左向右的结合性:数字在前,字符串字后,先计算出结果,再进行字符串的拼接。
System.out.println(1+2+"hello"); //3hello
System.out.println(1+2+"hello"+3+4);//3hello34
} }

2.5 %的作用

%是取余符号,我们可以进行取余运算,也叫做取模运算。另外%在Java中不但可以对整数进行取模,还可以对double进行取模操作。

public class TypeDemo04 {

    public static void main(String[] args) {
int c = 34;
//获取c这个数据中的十位,执行整除
System.out.println(c/10);
//获取c这个数据中的个位
System.out.println(c%10);
} }

2.6 自增与自减

对初学者来说,有两个符号可能会让你比较懵圈,一个是++,一个是--,这两个符号分别叫做自增和自减运算符。++是自增符号,根据++在变量前或变量后的位置不同,也具有不同的特点,--自减符号同样如此。++和--具有如下特点:

++和-- 既可以放在变量的后边,也可以放在变量的前边;

单独使用时, ++和-- 无论是放在变量的前边还是后边,结果都是一样的;

参与操作时,如果放在变量的后边,会先使用变量参与操作,再取变量的值进行++或者--;

参与操作时,如果放在变量的前边,会先取变量的值进行++或者--,后使用变量参与操作;

只有变量才能使用自增/自减运算符,常量不能使用自增与自减符号,因为常量不允许被修改。

public class TypeDemo04 {

    public static void main(String[] args) {
//++自增 与 --自减操作
int d = 10;
d++; //d = d + 1; 先使用,再自增
System.out.println(d); //11
++d;//先自增,再使用
System.out.println(d); //12 //先使用再自增:在本语句中,先使用变量d,在本语句结束之后再对变量d进行自增。
System.out.println(d++); //12 13
//先自增再使用:在本语句中,先对变量d进行自增,然后把自增后的结果在语句中进行输出。
System.out.println(++d); //14 //这个案例比较复杂,你好好琢磨一下吧
int x = 10;
int y = 8;
//执行过程:10 - 9 + 8 + 10 - 7 =12
System.out.println(x++ - --x + y-- + x++ - --y);
} }

【++变量】变量先+1,然后使用变量+1之后的值;【变量++】先使用变量原来的值,表达式结束时给变量+1。所在在本案例中,如果++在变量之后,比如d++,具有“先使用,再自增”的特点。如果++在变量之前,比如++d,具有“先自增,再使用”的特点。--自减符号也是如此。壹哥不建议初学者把++运算混入到常规运算中,容易把你给搞懵逼哦。

三、赋值运算符

1. 概念

在Java中,“=”是赋值运算符,而不是我们通常认知中的“等号”。赋值运算符用于将“=”右侧表达式的结果,赋值给“=”左侧的变量。另外,除了“=”这个赋值符号之外,还有另外几个扩展的赋值符号,所以目前常用的赋值符号有如下几个:

= += -= *= /= %=

2. 案例

2.1 赋值案例

以下是几个赋值运算符的基本使用案例。在下面的案例中,大家要注意除法的计算结果哦。

public class TypeDemo04 {

    public static void main(String[] args) {
//=赋值运算符
int a = 10;
a += 2; //12,相当于 a=a+2;
System.out.println("a="+a);
a -= 3; //9,a = a - 3;
System.out.println("a="+a);
a *= 4; //36,a = a * 4;
System.out.println("a="+a);
//注意:Java中的除法,36/5=7哦,不会等于7.2,想想这是为什么?
a /= 5; //7,a = a / 5;
System.out.println("a="+a);
a %= 6; //1,a = a % 6;
System.out.println("a="+a);
} }

2.2 扩展案例

为了让大家更好地理解赋值运算符,壹哥再给大家扩展一个案例。

public class TypeDemo04 {

    public static void main(String[] args) {
//=赋值运算符
//笔试题:short s1 = 1; short s2 = 1; s2 = s1 + s2的结果是什么? s2 += s1的结果是什么?
short s1 = 1;
short s2 = 1;
//类型提升:s1+s2变成了int类型
//此行代码会报错,因为运算中s提升为int类型,运算结果int赋值给short可能损失精度
// s2 = s1 + s2; //错误
//此行代码没有问题,这里隐含了强制类型转换,相当于s = (short) (s + 10);
s2 += s1; // 正确
System.out.println(s2);
} }

在这个案例中,我们一定要注意类型提升的问题。两个short变量s1和s2,s1+s2时会进行类型提升变成int,所以必须对结果进行强制类型转换才行,如下图所示:

但是当我们使用s2+=s1语句时,虽然计算结果与s2=s1+s2是相同的,但内部的执行原理却不同,这是因为扩展的赋值运算符都隐含了强制类型转换。s2 = s1 + s2;此行代码会报错,这是因为运算中s变量会提升为int类型,运算结果int赋值给short可能会损失精度。

而在s2+=s1语句中就没有问题,因为这里隐含了强制类型转换,相当于s2 = (short) (s2 + s1);不用进行再额外强制类型转换,这一点我们一定要注意!

四、关系运算符

1. 概念

在Java中,关系运算符,又叫做比较运算符, 或者叫做布尔运算符,主要是用于比较两个表达式的结果。常用的赋值符号有如下几个:

> >= < <= == !=

2. 案例

接下来我们再通过一些代码案例,来学习一下关系运算符的用法吧。我们在使用比较运算时,最终都会得到一个布尔类型的值。且在进行比较运算时,一定要注意其优先级。

public class TypeDemo04 {

    public static void main(String[] args) {
// 关系运算符
int a = 10;
int b = 20; System.out.println(a > b);
System.out.println(a >= b);
System.out.println(a < b);
System.out.println(a <= b);
System.out.println(a == b);
System.out.println(a != b); // 判断奇数与偶数
// 偶数条件: a % 2 == 0
// 奇数条件: a % 2 != 0
System.out.println("a != b " + (a != b));
System.out.println("a % 2 != 0 " + (a % 2 != 0));
} }

五、逻辑运算符

1. 概念

Java中的逻辑运算符, 主要有3个:逻辑与&&、逻辑或||、逻辑非!,如下所示:

&& || !

Java中的逻辑运算符,其实和数学中的与、或、非意思一致。 逻辑运算符大多数会和其他的运算符一起使用,主要做一些简单或复杂的逻辑运算。且通常都会和 if、for等逻辑表达式一起使用,使用格式为:表达式1 逻辑运算符 表达式2

2. 案例

接下来我们通过一个案例来演示逻辑运算符该如何使用。

public class TypeDemo04 {

    public static void main(String[] args) {
// 逻辑运算符,结果是boolean类型
int a = 17;
//a是否是一个偶数且大于10 //短路与:如果条件表达式中,前面的结果为false,就不再执行后面的表达式,效率较高。
System.out.println(a % 2 == 0 && a > 10);
//即使条件表达式中,前面的结果为false,依然会执行后面的表达式,效率较低。
System.out.println(a % 2 == 0 & a > 10); //a是一个奇数,或是否小于15
//短路或:如果条件表达式中,前面的结果为false,就不再执行后面的表达式,效率较高。
System.out.println(a % 2 != 0 || a < 15);
//即使条件表达式中,前面的结果为false,依然会执行后面的表达式,效率较低。
System.out.println(a % 2 != 0 | a < 15); //a是否是一个奇数?
System.out.println(!(a % 2 == 0)); //&、|的用法
int b = 10;
int c = 12;
boolean flag = b > c & b== 10;
System.out.println(flag);
} }

对于上述代码中的逻辑运算符,壹哥再给大家细说一下,我们要特别注意“短路与”和“短路或”的概念:

&&:逻辑与(短路与)。所有的结果为true,最终的结果才是true。&&属于短路与:逻辑与遵守短路求值的规则,即表达式1为假,表达式2就不再执行。即如果左边的表达式为真,右边的表达式就会执行;如果左边为假,右边不执行。

||:逻辑或(短路或)。所有的结果只要有一个为true,最终结果就是true。||属于短路或:遵守或也遵守短路求值的规则,即表达式1为真,表达式2就不在执行,否则就执行表达式2。

!: 逻辑非。对结果进行取反。

&:按位与。无论条件表达式的结果如何,都会执行完整个表达式,所在无论左边的表达式是真假,右边的表达式都要执行。

|:按位或。无论条件表达式的结果如何,都会执行完整个表达式。无论左边的表达式是真假,右边的表达式都要执行。

六、位运算符

1. 概念

我们知道,对任何编程语言而言,最终的操作都是用二进制表示,因为计算机的底层只认识二进制。而八进制、十进制或者十六进制,都是为了让开发人员方便开发而创立的。在Java中,也可以根据数的进制进行运算,这就需要位运算符的参与了。常用的位运算符有如下几个:

& | ^ ~ << >> >>>

注意:& 和 | 既是位运算符,也可以进行逻辑运算。

2. 案例

接下来我们通过一个案例来演示位运算符该如何使用。

public class TypeDemo04 {

    public static void main(String[] args) {
//位运算符 //按位与&
System.out.println(18 & 23); //按位或|
System.out.println(16 | 37); //按位亦或
System.out.println(13 ^ 34); //按位取反
System.out.println(~14);
System.out.println(~-18); //左移 <<
System.out.println(18 << 2); //右移 >>
System.out.println(23 >> 2);
System.out.println(-18 >> 2); //无符号右移 >>>
System.out.println(-23 >>> 2);
} }

针对上述代码,壹哥给大家解释一下:

2.1 按位与

按位与&的特点:相同数位都是1,最终的结果才是1。基本规则如下:

0 & 0 = 0;
0 & 1 = 0;
1 & 0 = 0;
1 & 1 = 1;

2.2 按位或

按位或|的特点:只要相同数位上有1,结果就是1。

2.3 按位异或

按位亦或的特点:相同数位相同为0,不同为1。

2.4 按位取反

按位取反的特点:将每一位上的数字取反。结论:数字+1取反。

2.5 左移

左移<<的特点:将二进制数位整体向左移动N位,低位补0。

2.6 右移

右移>>的特点:将二进制数位整体向右移动N位。如果是正数补0,负数补1。

2.7 无符号右移

无符号右移>>>的特点:将二进制数位整体向右移动N位。高位补0

PS:关于进制转换、原码、反码、补码等内容,壹哥会在后面的文章中专门讲解!

七、条件运算符

1. 概念

条件运算符,又叫做三目运算符,目前在 Java 中只有一个三目运算符 ? :三目运算的语法格式如下:

布尔表达式 ? 表达式1 : 表达式2

很多时候,三目运算都是 if 和 else 的简写。

2. 案例

public class TypeDemo04 {

    public static void main(String[] args) {
//条件表达式,三目运算符 //判断年龄,如果大于18岁,输出成年人,否则输出未成年人
int age = 70;
String s = age > 18 ? "成年人" : "未成年人";
System.out.println(s); //a和b比较,输出较大的数字
int a = 10;
int b = 20;
int num = a > b ? a : b;
System.out.println(num); //三目运算符嵌套使用
//判断年龄。如果大于18岁,输出成年人;但如果大于60岁,输出老年人,否则输出未成年人
String s1 = age > 18 ? age > 60 ? "老年人" : "成年人" : "未成年人";
System.out.println(s1);
} }

三目运算符虽然可以嵌套使用,但我们在开发时尽量不要这么使用,这样的代码可读性很差。

八、类型比较运算符

在Java中还有一个类型比较运算符instance of,用于对Java的对象类型进行比较,可以判断定义的变量是否属于某个类,该类可以是(接口、抽象类)。语法格式如下:

boolean = 变量 instanceof 类

因为目前我们还没有学习Java面向对象的内容,所以这里我们先做个了解,知道有这么一个符号就可以了。后面壹哥会在讲面向对象时,再单独对该符号的使用进行讲解。

------------------------------正片已结束,来根事后烟----------------------------

九、结语

至此,壹哥就把Java里的各种常见运算符给大家讲解完毕了,现在你学会了吗?其实这些运算符记忆起来并不复杂,算术运算符的含义和使用与数学里的一样,这根本就不用单独记忆。我们只需要去记一些较为特殊的运算符用法和特点,比如三目运算符、逻辑运算符、位运算符等。

十、今日作业

第一题

java中37.2%10的运算结果是多少?评论区告诉我吧

第二题

00101010(&)00010111语句的执行结果是哪个?

A. 00000010 B. 11111111 C. 00111111 D. 11000000

第三题

如何高效地计算出2的幂次方?评论区给出你的实现思路

一篇文章带你了解Java中的运算符的更多相关文章

  1. 一篇文章带你了解Java OOP思想

    Java OOP 思想深度刨析 Java面向对象编程 面向对象编程简称OOP(Object--对象.Oriendted--导向的.Programming--程序设计) 面向对象通俗来讲,就是指使用丰富 ...

  2. 一篇文章带你了解JavaScript中的语法,数据类型,流程控制语句以及函数

    作者 | Jeskson 来源 | 达达前端小酒馆 1 JavaScript有多重要啊,才能让我说说一下,其中的语法,操作符,数据类型,内置功能等. 语法: 在JavaScript中的变量,函数名和操 ...

  3. 一篇文章带你了解JavaScript中的变量,作用域和内存问题

    1 在JavaScript中的变量分别区分为两种: 一种为基本类型值,一种为应用类型值. 基本类型值指的是简单的数据段 引用类型值为可能由多个值组成的对象 引用类型的值是保存在内存中的对象,JavaS ...

  4. MYSQL(进阶篇)——一篇文章带你深入掌握MYSQL

    MYSQL(进阶篇)--一篇文章带你深入掌握MYSQL 我们在上篇文章中已经学习了MYSQL的基本语法和概念 在这篇文章中我们将讲解底层结构和一些新的语法帮助你更好的运用MYSQL 温馨提醒:该文章大 ...

  5. 一篇文章带你掌握主流数据库框架——MyBatis

    一篇文章带你掌握主流数据库框架--MyBatis MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射. 在之前的文章中我们学习了MYSQL和JDBC,但是这些东西远远不 ...

  6. 一篇文章带你掌握主流基础框架——Spring

    一篇文章带你掌握主流基础框架--Spring 这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容 那么简单说明一下Spring的必要性: Spring技 ...

  7. 一篇文章带你掌握主流服务层框架——SpringMVC

    一篇文章带你掌握主流服务层框架--SpringMVC 在之前的文章中我们已经学习了Spring的基本内容,SpringMVC隶属于Spring的一部分内容 但由于SpringMVC完全针对于服务层使用 ...

  8. 一篇文章带你掌握主流办公框架——SpringBoot

    一篇文章带你掌握主流办公框架--SpringBoot 在之前的文章中我们已经学习了SSM的全部内容以及相关整合 SSM是Spring的产品,主要用来简化开发,但我们现在所介绍的这款框架--Spring ...

  9. 一篇文章带你掌握MyBatis简化框架——MyBatisPlus

    一篇文章带你掌握MyBatis简化框架--MyBatisPlus 我们在前面的文章中已经学习了目前开发所需的主流框架 类似于我们所学习的SpringBoot框架用于简化Spring开发,我们的国人大大 ...

  10. 一篇文章带你了解服务器操作系统——Linux简单入门

    一篇文章带你了解服务器操作系统--Linux简单入门 Linux作为服务器的常用操作系统,身为工作人员自然是要有所了解的 在本篇中我们会简单介绍Linux的特点,安装,相关指令使用以及内部程序的安装等 ...

随机推荐

  1. react对于setState的写法

    react对于setState的写法,改变state的数组里边的值也可以这样写 [1,2,3,4,5].forEach((item)=>{ let arr={} arr[`list${item} ...

  2. Leetcode本地阅读器开发--01界面设计二

    返回项目声明及目录:Leetcode本地阅读器开发--总声明 继续上一节内容: 1.第一个内容是左边第一行的功能,读取默认路径和修改路径.此路径为本地阅读器的搜索题目的主目录. 为了整个程序都能读取工 ...

  3. std::unique_ptr release的使用

    在c++中,动态内存管理是通过new/delete 运算符来进行的.由于确保在正确的时间释放内存是很困难的,为了避免内存泄漏,更加容易,安全地使用动态内存,C++11标准库提供了两种智能指针类型来管理 ...

  4. AX2012 去掉浮点数后面的0

    static void Job116(Args _args) { str string1; real num1; ; num1 = 0.00; string1 = System.String::For ...

  5. 【逆向】HWP文档 分析调试技巧

    前言 HWP(Hangul Word Processor)文件是韩国主流文字处理软件Hangul Office(한글)专用的文档格式,Hangul 是一款由韩软公司(Hansoft)开发,在韩国人人皆 ...

  6. c++ 保存txt文件

    #include <iostream> #include <stdio.h> #include <fstream> #include <queue> # ...

  7. 4组-Beta冲刺-4/5

    一.基本情况 队名:摸鲨鱼小队 组长博客:https://www.cnblogs.com/smallgrape/p/15604878.html github链接:https://github.com/ ...

  8. jetson nano 4gb记录

    常用命令 Ctrl alt t 打开终端gnome-session-properties 打开开机自启动管理界面 ifconfig 查看ip xrandr --fb 1200x800 调节分辨率 ll ...

  9. python.字典方法。第三天

    当需要为字典中的键设置默认值时,当该键没有任何值时使用它.代码如下 spam={'name':'Pooka','age':'5'} if 'color' not in sapm; spam['colo ...

  10. MVCC原理

    MVCC MVCC (Multi-Version Concurrency Control) ,即多版本并发控制,利用记录的版本链和ReadView,来控制并发事务访问相同记录时的行为.ReadView ...