当前位置: 首页 > 面试题库 >

Java中的自动装箱与手动装箱

叶谦
2023-03-14
问题内容

为什么第二段代码更快?

Map<Integer, Double> map = new HashMap<Integer, Double>();
for (int i = 0; i < 50000; i++) {
    for (double j = 0.0; j < 10000; j++) {
        map.put(i, j);
    }
}

Map<Integer, Double> map=new HashMap<Integer, Double>();
for (int i = 0; i < 50000; i++) {
    for (double j = 0.0; j < 10000; j++) {            
        map.put(new Integer(i), new Double(j));
    }
}

问题答案:

自动装箱使用Integer.valueOf,内部将Integer对象缓存为小整数(默认情况下为-128至127,但是最大值可以使用“
java.lang.Integer.IntegerCache.high”属性进行配置-请参见Integer.valueOf的源代码) ,因此与new Integer直接调用不同。因为Integer.valueOf在调用之前可以快速检查整数值的大小new Integer,所以new Integer直接调用要快一些(尽管如果您有很多小整数,它会使用更多的内存)。Java中的分配非常快,并且执行GC的时间与活动的短期对象的数量成正比(即与垃圾的数量不成比例),因此GC也非常快。

但是取决于JVM版本和启用的优化,存在标量替换优化,它在分配短期对象时会产生更大的性能差异(在您的示例中,无法进行优化,因为您正在存储地图中的对象,但在许多其他情况下很有用)。

在最新的JVM版本中,进行了标量替换优化(在1.6.0_18中暂时禁用了转义分析),这意味着可以优化短期对象的分配。在JVM中进行标量替换时,有人制定了一个基准测试,其中有与您相似的代码。结果是使用原语的代码最快,使用显式new Integer()调用的代码几乎与使用原语的代码一样快,而使用自动装箱的代码要慢得多。这是因为使用自动装箱Integer.valueOf,并且至少在那时进行了标量替换优化,没有考虑这种特殊情况。从那时起,我不知道优化是否有所改进。



 类似资料:
  • 问题内容: 我是Java新手,因此对以下示例感到困惑。可以认为“ ==”符号会比较 Intger 和 Int中“自动装箱” Integer 之间的值,并比较Integer之间的引用地址吗? 那么双打和0/0呢? 结果是: 问题答案: 出现时,取消装箱将会进行。 例如: 但是何时出现,取决于情况。 如果boxing type出现在,它将进行比较。但是,如果base type出现在,而另一侧是boxi

  • 那么双打和0/0呢? 结果是:

  • 有以下代码: 它打印: 12 这个不能编译。为什么?

  • 本文向大家介绍自动装箱和拆箱?相关面试题,主要包含被问及自动装箱和拆箱?时的应答技巧和注意事项,需要的朋友参考一下 自动装箱是Java 编译器在基本数据类型和对应的对象包装类型之间做的一个转化。 比如:把int转化成 Integer,double转化成 Double,等等。反之就是自动拆箱。 原始类型: boolean,char,byte,short,int,long,float,double 

  • 问题内容: 从JDK 5.0开始,自动装箱/拆箱是在Java中引入的,这种技巧很简单而且很有帮助,但是当我开始测试包装器类和原始类型之间的不同转换时,我真的很困惑自动装箱的概念在Java中的工作原理: Boxing 尝试不同的情况下后(),这是由编译器所接受的唯一情况是,当值的上做作运算符右侧的类型是int。当我查看源代码时,发现它仅实现一个带参数的构造函数。 因此,我的结论是,自动装箱的概念基于

  • 自JDK5.0以来,Java引入了自动装箱/取消装箱。这个技巧很简单而且很有帮助,但是当我开始测试包装器类和原始类型之间的不同转换时,我真的很困惑自动装箱的概念在Java是如何工作的。例如: 拳击 在尝试了不同的情况(、、、)后,编译器接受的唯一情况是做作运算符右侧值的类型为。当我查看的源代码时,我发现它只实现了一个带有参数的构造函数。 所以我的结论是自动装箱的概念是基于在包装类中实现的构造函数。