在Java语言规范第三版,5.1.7 Boxing Conversion中,
If the value p being boxed is true, false, a byte, a char in the range /u0000 to /u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
这就是为什么符合规范的Java实现必须保证Integer的缓存至少要覆盖[-128, 127]的范围。
在网上查了一些资料,这个值是可以配置和指定的。配置涉及到较高级话题,在此不讨论。
这个内容在"JVM之池----String,Integer"中也有提及。http://blog.csdn.net/cuser_online/archive/2010/11/16/6013582.aspx
原谅比较白话,如下:
Integer a1 = 200;
Integer a2 = 200;
System.out.println(a1 == a2);//false
Integer a3 = 100;
Integer a4 = 100;
//Integer在 -128-127(flyweight(享元模式),可以节省内存开销)
System.out.println(a3 == a4);//true
以下一段话为个人根据String pool机制进行的猜测(暂时没找到具体资料,以前仿佛在哪看到过类似资料)。
针对Integer,JVM也对其进行了特殊处理。具体可描述为,对字面值在-128-127范围内的Integer,如果是直接以赋值形式创建Integer实例,则直接指向常量池中的对应的Integer实例。
换句话说,就是JVM在一启动时就开辟了一块空间,将字面值范围在-128-127内的Integer统统放到那里去,以后若有此范围内的Integer实例创建,则不需要在heap中创建了,直接指向池中已经创建好的对象。为什么这样做?当然是为了缓存和共享。
实际上这是享元模式的又一个经典应用。这是怎么实现的?一般是利用工厂和多例模式结合来做的。实际上如果将单例模式作一变通,就可以变成多例模式。上面几个模式在此不赘述。
注意,若上面的代码为:
Integer a3 = new Integer(100);
Integer a4 = new Integer(100);
System.out.println(a3 == a4)//false
因为指明了new创建实例方式,则不管什么共享了,直接在堆中创建对象。聪明的你,看过String类的机制,应该一下子就能明白了。