http://blog.hesey.net/2010/07/java-construction-of-integer-and-string.html
view sourceprint?01 public class test {
02 public static void main(String[] agrs) {
03 int a = 1000, b = 1000;
04 System.out.println(a == b); // true
05
06 Integer c = 1000, d = 1000;
07 System.out.println(c == d); // false
08
09 Integer e = 100, f = 100;
10 System.out.println(e == f); // true
11 }
12 }
答案:
来看JAVA源代码中Integer的
构造函数:
JDK1.5开始,Integer对象的赋值会自动调用Integer类的valueOf(int i)方法
view sourceprint?1 public static Integer valueOf(int i) {
2 final int offset = 128;
3 if (i >= -128 && i <= 127) {
4 return IntegerCache.cache[i + offset];
5 }
6 return new Integer(i);
7 }
而IntegerCache方法在这里:
view sourceprint?1 private IntegerCache() {
2 }
3 static final Integer cache[] = new Integer[-(-128) + 127 + 1];
4 static {
5 for (int i = 0; i < cache.length; i++)
6 cache[i] = new Integer(i - 128);
7 }
8 }
所以, 从JDK1.5开始,为了增强一系列基础类型对应对象的性能,
JVM预
缓存一部分常量,例如Integer预缓存-128~127这些数(实际上是一个 byte所能表示的范围),如果赋值数在此范围内,对象直接指向预缓存地址,如果不在,重新赋值(所以造成地址不同)。
验证代码:
view sourceprint?1 for (int i = -200; i < 200; i++) {
2 Integer a = i, b = i;
3 System.out.print(i + " ");
4 System.out.println(a == b);
5 }
结果:i为-128到127时,结果为true。
类似的问题还有几个月前让我很疑惑的字符串构造问题:
view sourceprint?01 class test {
02 public static void main(String[] agrs) {
03 String a = "Hello";
04 String b = "Hello";
05 System.out.println(a == b); //true
06
07 String c = new String("Hello");
08 String d = new String("Hello");
09 System.out.println(c == d); //false
10 }
11 }
这个则是和静态常量池有关了。
要学的还有很多。