黑马程序员技术交流社区

标题: 关于 += 运算符的问题 [打印本页]

作者: 麦田守望者0812    时间: 2012-5-19 08:32
标题: 关于 += 运算符的问题
short s1 = 1; s1 += 1;由于 += java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译
哪位知道java编译器对它进行怎样的处理

作者: 袁培育    时间: 2012-5-19 08:46
因为+=是赋值运算符而不是简单的算术运算符,它运行的过程是这样的,先计算s1+1的值,虽然s1是short,但在+=这个运算符里计算s1+1时并不将s1提升为int,而是仍按short进行加和,得到一个short的值再赋给s1。
作者: 冯越    时间: 2012-5-19 09:05
对于 s1 += 1,个人认为可以分为两部分,见下面代码:
Java代码  
short s1 = 1;  
s1 = (short)((int) s1 + 1);  

这样解释的原因可以再看下面的例子:
Java代码  
public class Test {  
    public void test1(){  
        short s1 = 1;  
        s1 = (short)((int) s1 + 1);  
    }  
      
    public void test2() {  
        short s1 = 1;  
        s1 += 1;  
    }  
}  

查看Test.class文件的字节码文件:
Java代码  
public void test1();  
   0  iconst_1  
   1  istore_1 [s1]  
   2  iload_1 [s1]  
   3  iconst_1  
   4  iadd  
   5  i2s  
   6  istore_1 [s1]  
   7  return  
     Line numbers:  
       [pc: 0, line: 4]  
       [pc: 2, line: 5]  
       [pc: 7, line: 6]  
     Local variable table:  
       [pc: 0, pc: 8] local: this index: 0 type: Test  
       [pc: 2, pc: 8] local: s1 index: 1 type: short  
   
public void test2();  
   0  iconst_1  
   1  istore_1 [s1]  
   2  iload_1 [s1]  
   3  iconst_1  
   4  iadd  
   5  i2s  
   6  istore_1 [s1]  
   7  return  
     Line numbers:  
       [pc: 0, line: 9]  
       [pc: 2, line: 10]  
       [pc: 7, line: 11]  
     Local variable table:  
       [pc: 0, pc: 8] local: this index: 0 type: Test  
       [pc: 2, pc: 8] local: s1 index: 1 type: short  

    除了11-13行和28-30行的内的行号不同之外,其余部分都一样。即这两上写法其实是等效的。
    s1 = (short)((int) s1 + 1);  可以简化为s1 = (short)(s1 + 1);因为从short到int JVM会自动提升类型。

    最后补充一点,JVM会自动提升类型的表达式为:
Java代码  
short +|-|*|/|% short = (int) short +|-|*|/|% (int) short;  
byte  +|-|*|/|% byte  = (int) byte  +|-|*|/|% (int) byte;  
char  +|-|*|/|% char  = (int) char  +|-|*|/|% (int) char;  

因为这些类型的运算很容易就会越界。它们之间的任意组合都会先转换成int,然后再运算,结果为int类型。但是遇到更高精度的操作数,如float、doubl,它们也会向float、double自动提升类型。自动提升类型除基本赋值外,都是向精度高的方向进行的。  对于short、byte、char的基本赋值,就像short s1 = 1;是int类型自动降低类型到short的。
作者: 宗士为    时间: 2012-5-19 09:11
short s1 = 1; s1 += 1

首先给short s1 赋值为1
s1 += 1 想当与是 s1 = s1 +  1;  
但是有一点不同的是
写成这种形式的    s1 = s1 +  1     s1是short型   1 是int型     s1 +  1 的话会自动转型成 int型,再赋值给s1的话要强制类型转换     所以要写成   s1 =(short) s1 +  1
如果写成s1 += 1   的话 += 会自动提升类型  就不用再写强制转换   
short s1 = 1; s1 += 1   编译可以通过
short s1 = 1 ; s1 = s1 +  1    不进行强转的话   编译会出错
作者: 麦田守望者0812    时间: 2012-5-19 11:03
袁培育 发表于 2012-5-19 08:46
因为+=是赋值运算符而不是简单的算术运算符,它运行的过程是这样的,先计算s1+1的值,虽然s1是short,但在+ ...

计算s1+1时并不将s1提升为int  内部机理是怎样的呢
作者: 麦田守望者0812    时间: 2012-5-19 11:09
冯越 发表于 2012-5-19 09:05
对于 s1 += 1,个人认为可以分为两部分,见下面代码:
Java代码  
short s1 = 1;  

在运行s1 += 1的过程中虚拟机做了强制类型转换吗如:s1 = (short)( s1 + 1);?
作者: 麦田守望者0812    时间: 2012-5-19 11:10
冯越 发表于 2012-5-19 09:05
对于 s1 += 1,个人认为可以分为两部分,见下面代码:
Java代码  
short s1 = 1;  

在运行s1 += 1的过程中虚拟机做了强制类型转换吗如:s1 = (short)( s1 + 1);?
作者: 曹俊    时间: 2012-5-19 11:10
shor s1 = 1
s1 += 1 等同于 s1 = s1 + 1,但两者有所不同。
s1 = s1 + 1 中s1 会被提升为int类型,运算后的结果还是int类型,无法赋值给short类型。
s1 += 1 中 += 运算后在给 s1 赋值,自动完成了转换类型的操作。
作者: 杨康    时间: 2012-5-19 11:17
首先,+=是一个运算符,只进行一次操作。对于你定义的short s =1 ,s = s +1. 因为1是java默认的int型,所以在short型的s与int型的1求和的时候,java会强制转换s的类型,将其转换为int型,以便保证运算的精准度,所以s+1后的和也是个int型,要把int型的和赋给short型的s ,java就会报错,损失精准度。 对于+= 则是直接将s与1求和后的值 直接赋定义的short,此过程没有转换类型过程。故可以运行




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2