java中a= b_Java中a=a+b 与 a+=b区别

这两种运算符的区别,可以有以下两个方面的比较: 执行效率和类型转换。

1、执行效率

就单纯的执行这两条语句,不考虑编译器的优化的话,a=a+b的执行效率是低于a+=b的,因为它多进行了一步中间变量的操作,而且会多占用一个变量的空间。而Java编译器默认对其进行了优化,优化之后两条语句都当做 a+=b来执行了,所以实际上是没有任何区别的。

2、类型转换

如下情况:

1 public classTest {2

3 public static voidmain(String[] args){4 int a = 2;5 float b = 6;6 a+=b; //right7 //a=a+b;//error

8 a=(int) (a+b); //right

9 }10 }

当使用a=a+b的时候,会抛出”Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from float to int“的异常,这是可以理解的,如果不使用(int)强制类型转换的话,float 是不能直接赋值给int 变量的。

我们将a=a+b注释掉,javac编译完之后,再使用反编译软件(例如XJad)打开Test.class文件,会发现源代码被解析成这样子:

1 public classTest2 {3

4 publicTest()5 {6 }7

8 public static voidmain(String args[])9 {10 int a = 2;11 float b =6F;12 a = (int)((float)a +b);13 a = (int)((float)a +b);14 }15 }

即a+=b进行了强制类型转换,和 a=(int)((float)a+b)是等价的!

到这里我们就明白了为什么a=a+b会抛出异常了。

原因:在Java中,在基本类型进行算术运算的时候,会发生小字节类型向大字节类型转换的现象。如图中 int 类型和float类型进行加法运算时会先将 a 转换为float类型,然后再和b相加。这样结果类型变成了float类型,如果这时候试图把float类型赋值给a时便会抛异常。

另外,对于short,byte,char 比int 字节数小的变量类型来说,运算结果会自动转换为int类型,如

1 byte a = 1 , b=2;2 b=a+b;

1 byte a = 1;2 short b =2;3 b=a+b;

都会抛出”Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from int to byte“类似的异常,可以看出a+b结果变成了int类型。

这是由于Java编译器会在编译期或者运行期将byte和short类型的数据带符号扩展为相应的int类型数据,将boolean和char类型数据零位扩展为相应的int类型数据。因此,在处理boolean 、byte、short 和 char 类型的数组时,也会用相应的int类型的字节码指令来处理。因此,大多数对于上述类型数据的操作,实际上都是使用相应的 int 类型作为运算类型。

如果是final 修饰的变量,进行运算的时候则不会出现类型转换异常。

1 public classTest {2 final int d = 3;3 public static voidmain(String[] args){4 final short a = 1;5 final short b =2;6 short c=a+b;7 }8 }

编译后使用反编译软件打开后,代码被解析成了这样:

1 public classTest2 {3

4 final int d = 3;5

6 publicTest()7 {8 }9

10 public static voidmain(String args[])11 {12 short a = 1;13 short b = 2;14 short c = 3;15 }16 }

可以看到,对于final 修饰的基本类型的变量来说,他们之间的运算直接就被硬编码成了直接赋值语句,连中间结果都没有了,类型转换的异常也就没了。

此外,我们可以注意到,对于方法内的 final 变量 a , b 来说,编码时被直接省略了。而Test 类的final 成员变量 d 依然保留着final 属性。

所以说,是否使用final修饰方法中普通变量对JVM来说没有区别!使用final修饰方法中普通变量主要是为了给Java前端编译器(如javac)看的!也就是说方法中被final修饰的普通变量在前端编译时被javac检查并保证该变量不会在作用域内被改变新值,但被编译成字节码后用于修饰方法中普通变量的final就已经不存在了!说的再具体点就是你用或不用final修饰方法中普通变量而生成的字节码文件(.class文件)没有区别。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值