java中,在一些情况下会有自动装箱与自动拆箱。
自动拆箱/装箱是在编译期,依据代码的语法,决定是否进行拆箱和装箱动作。
装箱过程:把基本类型用它们对应的包装类型进行包装,使基本类型具有对象特征。
拆箱过程:与装箱过程相反,把包装类型转换成基本类型。
正是因为装箱与拆箱,会发现一个很有趣的现象。
先看下面代码1:
public static void main(String[] args) { Integer a= 1; Integer b= 1; System.out.println("a==b ?"+ (a==b)); }
运行上面代码,结果是: a==b ?true
我们在运行下面代码2:
1 public static void main(String[] args) { 2 Integer a= 255; 3 Integer b= 255; 4 System.out.println("a==b ?"+ (a==b)); 5 }
运行上面代码,结果是: a==b ?false
是不是很奇怪?
这是因为:在java中,Integer对int类型自动装箱的时候,会有一个缓存机制。这个缓存机制认为对于int 值在 一个字节范围内的数:-128-127,是使用频率高的数,为了节省内存,对于这个范围的int自动装箱的时候,同一个int值,只会生成一个对象。
我们对于代码2,利用反编译工具,查看编译后的class文件,如下
1 public static void main(String[] args) 2 { 3 Integer a = Integer.valueOf(255); 4 Integer b = Integer.valueOf(255); 5 System.out.println("a==b ?" + (a == b)); 6 }
可以看到,jdk是利用Integer.valueOf()这个方法来对int基本类型自动装箱的。
如果我们用new Integer()来对一个int类型封装(非自动装箱),就没有缓存机制(忽略int的值是否在-128-127)。
如下代码:
1 public static void main(String[] args) { 2 Integer a = new Integer(1); 3 Integer b = new Integer(1); 4 System.out.println("a==b ?"+ (a==b)); 5 }
运行结果: a==b ?false