常量池包含:8种基本数据类型(byte、short、int、float、long、double、char、boolean)、部分包装类(Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现)、对象型(如String及数组)还包含一些以文本形式出现的符号引用,比如:(类和接口的全限定名、字段的名称和描述符、方法和名称和描述符)
其中Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,也即对象不负责创建和管理大于127的这些类的对象
如下:
package test; public class Test1 { public static void main(String[] args) { Integer i1 = new Integer(1); Integer i2 = new Integer(1); // i1,i2分别位于堆中不同的内存空间 System.out.println(i1 == i2);// 输出false Integer i3 = 1; Integer i4 = 1; // i3,i4指向常量池中同一个内存空间 System.out.println(i3 == i4);// 输出true // 很显然,i1,i3位于不同的内存空间 System.out.println(i1 == i3);// 输出false // 0~127的整型包装类从常量池取 Integer i5 = 127; Integer i6 = 127; System.out.println(i5 == i6);// 输出true // 超过127的包装类型不从常量池取 Integer i7 = 128; Integer i8 = 128; System.out.println(i7 == i8);// 输出false // 基本数据类型从常量池取 int i9 = 128; int i10 = 128; System.out.println(i9 == i10);// 输出true // 浮点型的包装类不从常量池取 Double d1 = 1.00; Double d2 = 1.00; System.out.println(d1 == d2);// 输出false // s1,s2分别位于堆中不同空间 String s1 = new String("hello"); String s2 = new String("hello"); System.out.println(s1 == s2);// 输出false // s3,s4位于池中同一空间 String s3 = "hello"; String s4 = "hello"; System.out.println(s3 == s4);// 输出true } }
注意:
package test; public class Test1 { public static void main(String[] args) { String s1 = "Programming"; String s2 = new String("Programming"); String s3 = "Program"; String s4 = "ming"; String s5 = "Program" + "ming"; String s6 = s3 + s4; System.out.println(s1 == s2);//false System.out.println(s1 == s5);//true System.out.println(s1 == s6);//false System.out.println(s1 == s6.intern());//true System.out.println(s2 == s2.intern());//false } }
最后
细节决定成败,写代码更是如此。
在JDK5.0之前是不允许直接将基本数据类型的数据直接赋值给其对应地包装类的,如:Integer i = 5;
但是在JDK5.0中支持这种写法,因为编译器会自动将上面的代码转换成如下代码:Integer i=Integer.valueOf(5);
这就是Java的装箱.JDK5.0也提供了自动拆箱. Integer i =5; int j = i;