首页 > 其他分享 >关于使用new Integer还是Integer.valueOf的研究

关于使用new Integer还是Integer.valueOf的研究

时间:2023-09-04 15:06:27浏览次数:46  
标签:lang cache java valueOf static new Integer public


作者:fbysss

前言:

最近看到这样的说法:使用Integer.valueOf代替new Integer更有效率,原因是研究了Integer源码,发现有一个缓存可以利用。

对此我也一探究竟。发现这其实与Java的自动装箱拆箱有关,直接使用Integer i =数值的方式即可。

通过字节码研究是比较有效的方式。那我们来看看吧:


-------------------
Integer.valueOf源码:
-------------------

public static Integer valueOf(int i) {
 final int offset = 128;
 if (i >= -128 && i <= 127) { // must cache 
     return IntegerCache.cache[i + offset];
 }
        return new Integer(i);
    }

-------------------
IntegerCache 源码(jdk1.6.0_12):
-------------------

源码1:

private static class IntegerCache {
 private IntegerCache(){}


 static final Integer cache[] = new Integer[-(-128) + 127 + 1];//注意这个cache是final的


 static {
     for(int i = 0; i < cache.length; i++)
 cache[i] = new Integer(i - 128);
 }
public class TestInt { 



 /** 

  * @param args 

  */ 

 public static void main(String[] args) { 

 int i =200; 

 i ++; 

 } 

}



---------------------


javap -c TestInt


---------------------

public class com.sss.newage.test.TestInt extends java.lang.Object{ 

public com.sss.newage.test.TestInt(); 

  Code: 

   0:   aload_0 

   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V 

   4:   return 



public static void main(java.lang.String[]); 

  Code: 

   0:   sipush  200 

   3:   istore_1 

   4:   iinc    1, 1 

   7:   return 



}

源码2:


public class TestInt { 



 /** 

  * @param args 

  */ 

 public static void main(String[] args) { 

 Integer i =200; 

 i ++; 

 } 

}

---------------------


javap -c TestInt


---------------------


public class com.sss.newage.test.TestInt extends java.lang.Object{ 

public com.sss.newage.test.TestInt(); 

  Code: 

   0:   aload_0 

   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V 

   4:   return 



public static void main(java.lang.String[]); 

  Code: 

   0:   sipush  200 

   3:   invokestatic    #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 

   6:   astore_1 

   7:   aload_1 

   8:   invokevirtual   #22; //Method java/lang/Integer.intValue:()I 

   11:  iconst_1 

   12:  iadd 

   13:  invokestatic    #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 

   16:  astore_1 

   17:  return 



}

我们可以看到:

1.第3行(行标为3)调用了Integer.valueOf,一旦数字在缓存窗口中,则能够提高效率,那么我们可以认为,缓存不用白不用,的确比new Integer要好。

2..第8行(行标为8)进行了自动拆箱(intValue),目的是进行数字的加1运算


3.注意第13行,运算完毕之后,再次进行装箱(valueOf),这些运算都不影响cache本身,所以cache设计成只读即可,也不存在线程安全问题。





源码3:修改Integer i =200;为Integer i =Integer.valueOf(200);

public class TestInt { 



 /** 

  * @param args 

  */ 

 public static void main(String[] args) { 

 Integer i =Integer.valueOf(200); 

 i ++; 

 } 

} 



public class com.sss.newage.test.TestInt extends java.lang.Object{ 

public com.sss.newage.test.TestInt(); 

  Code: 

   0:   aload_0 

   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V 

   4:   return 



public static void main(java.lang.String[]); 

  Code: 

   0:   sipush  200 

   3:   invokestatic    #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 

   6:   astore_1 

   7:   aload_1 

   8:   invokevirtual   #22; //Method java/lang/Integer.intValue:()I 

   11:  iconst_1 

   12:  iadd 

   13:  invokestatic    #16; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 

   16:  astore_1 

   17:  return 



}

可以看到,使用Integer i = 200;与Integer i = Integer.valueOf(200);是等价的,从程序员读写习惯来看,使用Integer i = 200;的形式更好






------------------------

注意一点:

------------------------

最新版本的Jdk,Integer有改写,IntegerCache 的缓存窗口可以配置(通过JVM参数 -XX:AutoBoxCacheMax设置)。


JDK1.6.0_27相关源码


/**
     * Cache to support the object identity semantics of autoboxing for values between 
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage. During VM initialization the
     * getAndRemoveCacheProperties method may be used to get and remove any system
     * properites that configure the cache size. At this time, the size of the
     * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>.
     */


    // value of java.lang.Integer.IntegerCache.high property (obtained during VM init)    static void getAndRemoveCacheProperties() {
        if (!sun.misc.VM.isBooted()) {
            Properties props = System.getProperties();
            integerCacheHighPropValue =
                (String)props.remove("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null)
                System.setProperties(props);  // remove from system props
        }
    }


    private static class IntegerCache {
        static final int high;
        static final Integer cache[];


        static {
            final int low = -128;


            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;


            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }


        private IntegerCache() {}
    }

本文编写时间仓促,若有描述不妥或论证有问题的地方,欢迎各位交流、指正。

标签:lang,cache,java,valueOf,static,new,Integer,public
From: https://blog.51cto.com/u_16245757/7350796

相关文章

  • PositiveSmallIntegerField、SmallIntegerField和IntegerField
    当您在Django中定义模型时,有几种不同的整数字段类型可供选择,包括PositiveSmallIntegerField、SmallIntegerField和IntegerField。以下是这三种整数字段类型的比较:PositiveSmallIntegerField(正小整数字段):用于存储小的非负整数值。范围:0到32767。适用于期望小的正值的字段,例......
  • 2个Integer比较不能用 ==
    举例子Integernum1=10;Integernum2=10;System.out.println(num1==num2);//trueIntegernum3=200;Integernum4=200;System.out.println(num3==num4);//falseIntegernum5=newInteger(10);Integernum6=newInteger(10);System.out.println(num......
  • 平台工程动态 Monthly News 2023-8
    了解最新行业动态,洞察平台工程本质。平台工程月度动态2023-8   注:您所阅读的内容来自平台工程社区基于网络公开资料整理推荐,如您希望自己的内容也出现在月度动态,欢迎一起参与,详见文末。本期内容预览:新闻速递|中国信通院发布铸基计划TISC企业级平台工程综合能力要......
  • What's the best approach for generating a new API key?
    https://stackoverflow.com/questions/14412132/whats-the-best-approach-for-generating-a-new-api-keyEdit:I'vespoketoafewfriends(email/twitter)andtheyrecommendedjustusingaGUIDwiththedashesstripped.......
  • Integer缓存机制随笔(清晰)
    总体主要分为两个方面①比较的是值一、基本数据类型与引用数据类型进行比较时,引用数据类型会进行拆箱,然后与基本数据类型进行值的比较举例:inti=12;Integerj=newInteger(12);i==j返回的是true二、引用数据类型与基本数据类型进行比较(equals方法),基本数......
  • 泛微E-cology ifNewsCheckOutByCurrentUser.dwr SQL注入漏洞
    漏洞描述泛微E-cology的ifNewsCheckOutByCurrentUser.dwr文件存在SQL注入漏洞。漏洞复现fofa语法:app="泛微-协同办公OA"登录页面如下:POC:POST/dwr/call/plaincall/CptDwrUtil.ifNewsCheckOutByCurrentUser.dwrHTTP/1.1Host:User-Agent:Mozilla/5.0(WindowsNT5.1)A......
  • vue --version 运行出现throw new ERR_SYSTEM_ERROR 错误
    (1)根据错误提示信息,找到出错入口文件:E:\SVN\zlpt\node_modules\node-ipc\entities\Defaults.js然后指定位置添加如下代码即可:constos=require('os');os.hostname=()=>"localhost";......
  • return new 内存泄漏
    样例如下:#include<iostream>classB{public:intFun(){return100;}}classA{public:B*CreateB()//new了个B对象{returnnewB();}}intmain(){A*aa=newA();std::cout<&......
  • newtonsoft.json
    https://www.newtonsoft.com/jsonProductproduct=newProduct();product.Name="Apple";product.Expiry=newDateTime(2008,12,28);product.Sizes=newstring[]{"Small"};stringjson=JsonConvert.SerializeObject(product);//{......
  • newInstance() 和 new 有什么区别
    在初始化一个类,生成一个实例的时候,有newInstance()和new两种方式。用newInstance与用new是区别的,区别在于创建对象的方式不一样。前者是使用类加载机制,后者是使用反射机制。Java中工厂模式经常使用newInstance来创建对象,如:Classc=Class.forName(“A”);factory=(AInterface......