对于 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的。 |