JAVA基础 表达式 运算符 优先级

一、运算符 和 表达式 概述

1、运算符是指进行特定操作的符号,也叫操作符。通过运算符可以对一个或多个进行运算,并获取运算结果。

2、表达式是指由数字、算符、数字分组符号(括号)、自由变量和约束变量等以能求得数值的有意义排列方法所得的组合。

说明:用运算符连起来的式子叫做表达式,如a+b,13+a;单独一个变量(if语句中的),也可叫表达式。

注意:

1、表达式有意义时,会先自动计算表达式结果,再赋值或打印。

2、表达式中的数据类型不同时,表达式的运算结果将会是数据范围大的那种。(byte/short/char  这三种类型在做+运算的时候,会首先被自动提升为int类型,再计算)

3、凡是用了比较运算符的表达式,其结果都是boolean型,这种表达式也叫条件表达式

二、运算符分类

1、算术运算符  + - * / % ++  --  

基本四则运算运算和数学一样(/除外)。

1.1  /运算符

表达式  整数类型/整数类型  结果为整数类型(小数部分精度自动损失)。

表达式中有浮点数(浮点数范围大,整数类型会自动隐式转换为浮点数),表达式结果返回浮点数类型。

1.2  %运算符  取余运算

语法: 被模数/模数;

取余运算。表达式结果的正负号与被模数相同,与模数无关。

1.3、+运算符

(1)对于数值来说,就是加法运算

(2)对于char类型来说,计算之前,char会被提升为int在做加法运算。

(3)对于字符串String来说,加号代表字符串连接操作(String类两个方向都重载了+运算符),结果返回字符串。

1.4、自增运算符 ++   (注意区分变量和表达式。 变量立刻加1,表达式看前++还是后++)

    使变量在自身基础上加1。两种方式  后++(a++)和 前++(++a),不管哪种方式,只要使用自增运算符,原变量a立即+1。

差异: 表达式a++ 和 ++a 的值不同         //变量a 和 a++ 是两回事。 a是变量, a++ 或 ++a 是表达式

    表达式a++结果是原变量的值,表达式++a结果是  原变量的新值即自增以后的值。

注意:自增运算符不会改变变量本身的数据类型(比如,byte,short即使自增,也不会升级成int)

1.5、同理自减运算符 --

    使变量在自身基础上-1。两种方式  后--(a--)和 前--(--a),不管哪种方式,只要使用自增运算符,原变量a立即-1。

差异:表达式a-- 和 --a 的值不同         //变量a 和 a--是两回事。 a是变量, a-- 或 --a 是表达式

    表达式a--是原变量的值,表达式--a是  原变量的新值即自减以后的值。

2、赋值运算符 = -= += *= /= %=

将等式右边的值赋值给左边的变量。赋值运算符不改变左值数据类型。

注意:= 两边数据类型不同的时候,可能出现错误的赋值直接编译不通过(大范围赋值给小范围)。其他情况会将右值自动隐式转换成和左值相同的数据类型。

exp:

short s1 = 10;

s1= s1+2; //编译失败,右边表达式自动升级为int,int赋值给byte 编译不通过

s1+=2;  //s1=12,赋值运算符不改变左值数据类型,因此s1仍然为byte

进阶:关于变量赋值

如果变量是基本数据类型,此时赋值的是变量所保存的数据值

如果变量时引用数据类型(对象或数组),此时赋值的是变量所保存的地址值。//此方法会导致变量指针指向堆内同一代码块

3、比较运算符(关系运算符)

     比较运算符的结果都是boolean型,也就是要么是true,要么是false。所以凡是用了比较运算符的表达式,其结果都是boolean型,这种表达式也叫条件表达式

注意:比较运算符比较的时候,如果运算符两边基本数据类型不一致,会自动变量提升以后,再比较值。

           如果比较运算符比较的时候,如果运算符两边是引用数据类型,则是比较两边的地址是否一致

4、逻辑运算符  (注意区分位运算符)

    逻辑运算符操作的都是boolean类型的变量(逻辑运算符操作的变量多数来自于上面比较运算符比较的结果)。

异或:a和b 相异 就true

结论:开发中,推荐使用短路版,因为目的是判断整个表达式逻辑,而不是计算表达式。短路版效率更高。

逻辑与& 和 短路与&&         表达式1 &(&)表达式2;

& 和 && 的运算结果相同。

差异:

逻辑与: 会将表达式1和表达式2都进行计算得到结果后,再判断整个逻辑表达式。

短路与:一旦表达式1判定为false,则整个逻辑表达式已经为false,就不会再计算表达式2(表达式2被短路)。

exp:

boolean b2 = false; 

int num2 = 3;

if(b2 && (num2++>0)) {}      //此时b2为false,整个表达式已经为false,短路与不会再判定num2++, 所以num2依然为3

逻辑或| 与 短路或 ||       表达式1 |(||)表达式2;

| 和 || 的运算结果相同   

差异:

逻辑或:会将表达式1和表达式2都进行计算得到结果后,再判断整个逻辑表达式。

短路或:一旦表达式1判定为true,则整个表达式已经为true,就不会再计算表达式2(表达式2被短路)

5、三元运算符 (可简化某些简单的if...else 语句,但是如果有嵌套,为了保持代码可读性,还是用if...else吧)

说明:条件表达式结果为boolean类型,根据条件表达式的布尔计算结果,决定执行表达式1 或 表达式2

三元运算符可以嵌套使用  (嵌套后可读性很差,不建议嵌套)

注意:由于可以声明一个变量去接收 表达式1 或 表达式2 都可以计算出某个结果。因此表达式1 和 表达式2 的结果需要尽量是声明变量的数据类型,至少要能够隐式转换成变量的类型(实际上一定会发生隐式转换)。 

exp: double num = (m>n)?2 : 1.0  // 表达式1为int,表达式2为double。 都可以赋值给变量double num,只是2会被隐式转换。

exp: Object o1 = true?new Integer(1) : new Double(2.0) ;

      System.out.println(o1); //输出1.0

Integer 自动拆包为1,隐式转换为 double型1.0。再自动装包为Double(1.0),此时Object o1= new Double(1.0) 。println(o1)指 o1.toString。 由于多态性,自然是用Double类的 toString,因此输出10

6、位运算符(自己开发极少使用,但看其他API的原码会有)

位运算是直接对整数型数据的二进制(注意计算机底层数据都是以补码储存进行运算。

注意:位运算符的 &、|  、^  标识和 逻辑运算符 相关标识长得一模一样。区别方法,就是看运算符两边的表达式的类型,如果是布尔类型就是逻辑运算符。如果是数值类型,就是位运算符。

算法: (一定要想象)

1、左移<<(补最低位),先写出当前数的二进制。然后根据要求进行位运算,溢出部分丢弃,空出部分补0。

2、右移>>(补最高位),先写出当前数的二进制。然后根据要求进行位运算,溢出部分丢弃,空出部分负数补1正数补0。(因为负数最高位是1,正数最高位是0)

3、无符号右移>>>(补最高位),不管操作数是正数负数,一律补0

4、其他位运算符很简单,直接把操作数二进制的补码写出来,按照规则直接操作就是了。

重要结论(可自行用算法验证):

1、<<:在一定范围内,每向左移1位,相当于*2

2、 >>:在一定范围内,每向右移1位,相当于/2

面试题:最高效的方式计算2*8?  2<<3  或  8<<1 //计算机本身是二进制,二进制操作自然是最高效方式

三、运算符的优先级

注意:表格里面一元运算符、三元运算符、赋值运算符 是从右向左运算,其余都是从左向右运算。

技巧:() 优先级那么高,可以利用()提高任何优先级。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值