Integer的自动缓存大小

来源:互联网 发布:手机店进销存软件 编辑:程序博客网 时间:2024/05/22 09:43

在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类的机制,应该一下子就能明白了。