装箱与拆箱
1.装箱和拆箱是如何实现的
- 从反编译的字节码中可以看出,在装箱的时候自动调用的是interger的valueOf(int)方法。而在拆箱的时候自动调用的是interger的intValue方法
2.相关的问题
- 下面这段代码的输出结果是什么?
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
但是事实上输出结果是:
true
false
- 原因
通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。
3.关于类型转化
-
boolean类型与其他基本类型不能进行类型的转换(既不能进行自动类型的提升,也不能强制类型转换), 否则,将编译出错。
-
byte型不能自动类型提升到char,char和short直接也不会发生自动类型提升(因为负数的问题),同时,byte当然可以直接提升到short型。
-
当对小于int的数据类型(byte, char, short)进行运算时,首先会把这些类型的变量值强制转为int类型进行计算,最后会得到int类型的值。因此,如果把2个short类型的值相加,最后得到的结果是int类型,如果需要得到short类型的结果,就必须显示地运算结果转为short类型。
例:
public class Main {
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d);//true
System.out.println(e==f);//false
System.out.println(c==(a+b));//true ( a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等)
System.out.println(c.equals(a+b));//true
System.out.println(g==(a+b));//true(比较数值)
System.out.println(g.equals(a+b));//false(比较对象引用)
System.out.println(g.equals(a+h));//true
}
}