zoukankan      html  css  js  c++  java
  • 【转】Java常量池详解

    今天My partner问我一个让他头疼的Java question,求输出结果:

    1. /** 
    2.  *  
    3.  * @author DreamSea 2011-11-19 
    4.  */ 
    5. public class IntegerTest { 
    6.     public static void main(String[] args) {     
    7.         objPoolTest(); 
    8.     } 
    9.  
    10.     public static void objPoolTest() { 
    11.         Integer i1 = 40
    12.         Integer i2 = 40
    13.         Integer i3 = 0
    14.         Integer i4 = new Integer(40); 
    15.         Integer i5 = new Integer(40); 
    16.         Integer i6 = new Integer(0); 
    17.          
    18.         System.out.println("i1=i2 " + (i1 == i2)); 
    19.         System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); 
    20.         System.out.println("i4=i5 " + (i4 == i5)); 
    21.         System.out.println("i4=i5+i6 " + (i4 == i5 + i6));     
    22.          
    23.         System.out.println();         
    24.     } 

    输出结果:

    i1=i2true
    i1=i2+i3   true
    i4=i5false
    i4=i5+i6true

    看起来比较Easy的问题,但是Console输出的Result和我们所想的确恰恰相反,我们就疑惑了,这是为什么咧?

    最后通过网上搜索得知Java为了提高性能提供了和String类一样的对象池机制,当然Java的八种基本类型的包装类(Packaging Type)也有对象池机制。

    Integer i1=40;Java在编译的时候会执行将代码封装成Integer i1=Integer.valueOf(40);通过查看Source Code发现:

    Integer.valueOf()中有个内部类IntegerCache(类似于一个常量数组,也叫对象池),它维护了一个Integer数组cache,长度为(128+127+1)=256,Integer类中还有一个Static Block(静态块)。

    从这个静态块可以看出,Integer已经默认创建了数值【-128-127】的Integer缓存数据。所以使用Integer i1=40时,JVM会直接在该在对象池找到该值的引用。也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的缓存池中查找有木有值为40的对象,如果有直接返回该对象的引用;如果没有,则使用New keyword创建一个对象,并返回该对象的引用地址。因为Java中【==】比较的是两个对象是否是同一个引用(即比较内存地址),i2和i2都是引用的同一个对象,So i1==i2结果为”true“;而使用new方式创建的i4=new Integer(40)、i5=new Integer(40),虽然他们的值相等,但是每次都会重新Create新的Integer对象,不会被放入到对象池中,所以他们不是同一个引用,输出false。

    对于i1==i2+i3、i4==i5+i6结果为True,是因为,Java的数学计算是在内存栈里操作的,Java会对i5、i6进行拆箱操作,其实比较的是基本类型(40=40+0),他们的值相同,因此结果为True。

    好了,我想说道这里大家应该都会对Integer对象池有了更进一步的了解了吧,我在诺诺的问一句如果把40改为400猜猜会输出什么?

    i1=i2false
    i1=i2+i3true
    i4=i5false
    i4=i5+i6true

    这是因为Integer i1=400,Integer i2=400他们的值已经超出了常量池的范围,JVM会对i1和i2各自创建新的对象(即Integer i1=new Integer(400)),所以他们不是同一个引用。

    原文链接:http://www.cnblogs.com/DreamSea/archive/2011/11/20/2256396.html


     



  • 相关阅读:
    Eclipse 导入项目乱码问题(中文乱码)
    sql中视图视图的作用
    Java基础-super关键字与this关键字
    Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解
    Android View和ViewGroup
    工厂方法模式(java 设计模式)
    设计模式(java) 单例模式 单例类
    eclipse乱码解决方法
    No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案
    【转】使用 Eclipse 调试 Java 程序的 10 个技巧
  • 原文地址:https://www.cnblogs.com/ssslinppp/p/4649420.html
Copyright © 2011-2022 走看看