Java 的包装类型,自动装箱与拆箱
Java 作为一门面向对象的语言,仍然保留了基本的几种值类型(int,short,long,byte,char,boolean,float,double)。当然为了方便开发人员使用也提供了对应的包装类,(Integer,Short,Long,Byte,Char,Boolean,Float,Double),并且在 Java 1.5 中开始提供了自动装箱(boxing)和拆箱(unboxing)特性。
自动装箱的主要作用是方便在值类型和包装类型之间切换,比如可以直接在源代码里将值类型赋值给包装类型或反之,使用 == 来比较值类型和包装类型的值。这里提到是源代码里这样做是因为自动装箱/拆箱特性主要由编译器帮我们完成。
当我们编写以下一段程序时
1 | int a = new Integer(5); |
- 其中第一行代码需要将包装类型赋值给值类型,编译器会生成等效于
int a = new Integer(5).intValue();
的代码 - 对于第二行,则有
Integer b = Integer.valueOf(6);
- 而对于值类型与包装类型的比较,则会先将包装类型转为基本类型,即
assert(a.intValue() == b);
关于包装类型的缓存
根据 Java 语言规范(JLS8,§5.1.7),包装类型会对部分值做缓存,在像 Integer.valueOf(int)
这样的方法中起作用,所以会出现 Integer a = 5; Integer b = 5; assert(a == b);
的情况。
If the value p being boxed is an integer literal of type int between -128 and 127 inclusive (§3.10.1), or the boolean literal true or false (§3.10.3), or a character literal between ‘\u0000’ and ‘\u007f’ inclusive (§3.10.4), then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.