---

2015/10/25

layout: post
title: "Java基础"
category: Reading Notes

tags: ["读文章", “Java”]

{% include JB/setup %}

  • 做基本运算(如+、-、/、<<、>>、>>>、~、等),当两个操作数的类型是byte,short,char,int之一的时候,结果的类型是int;
  • 做整数基本运算时,当一个操作数是long,结果是long
  • 不加任何修饰的整数字面值默认就是int类型。

    short s1 = 1; //OK
    
    short s2 = s1 + 1; //ERROR
    

上面的第一句1整形字面值,它的类型是int,为什么可以直接赋值给short呢?因为字面值都是常量,编译器能很容易的检测出它到底在不在short所能表示的值的范围内。当写成short s1 = 32768的时候,编译就知道short容不下32768了,就会报错。

而对于第二句,s1是short类型,1是int类型,结果是int类型,自然不能自动赋值给short类型的s2了,因为有潜在的高位有效值被截断的风险。可能会有人想,上面s1已经赋值了一个字面值,对于下面的s2,编译器应该也可以计算出它的值啊。如果s1是final的,确实会这样,但s1是变量,编译器是无法预测它会不会在运行期改变的,即使它可能不会改变。

short s = 1;
s = s + 1; //error
short s = 1;
s += 1; //ok

第二段代码编译后的字节码:
0:   iconst_1
1:   istore_1
2:   iload_1
3:   iconst_1
4:   iadd
5:   i2s
6:   istore_1
  • 指令0,1做了short s = 1操作,
  • 指令2,3,4做了s+1的操作,
  • 第5条是关键,做了一个强制转换,将int转换为short,
  • 第6条将强制转换的结果存回变量s

综上可以看到(其中type为byte,short,char,int之一,value可为变量可为常量,类型可为byte,short,char,int,float,double,long):

type s = value;
s += ovalue;//ok

逻辑上等价于(说逻辑上是因为type为int的时候并不存在强制转换,但结果是相同的):

type s = value;
s = (type)(s + ovalue);