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

自动装箱的性能影响

冯新知
2023-03-14
问题内容

通常,编译器会生成代码以执行装箱和拆箱。但是,如果不需要带框的值,编译器怎么办?(Oracle标准)编译器是否足够智能以优化它?

看一下这个方法:

public static void requireInRange(int index, Object[] array) {
    if(index < 0 || index >= array.length)
        throw new IndexOutOfBoundsException();
}

唯一相关的信息是array.length,因此将例如数组的每个值装箱将是无用的。像下面的代码:

int[] anArray = {3, 4, 2};
requireInRange(3, anArray);

编译器会实际插入用于对数组的每个值进行装箱的代码吗?


问题答案:

您的代码中没有自动装箱。实际上,鉴于:

public static void requireInRange(int index, Object[] array) {
   ...
}

int[] anArray = {3, 4, 2};
requireInRange(3, anArray); // DOES NOT COMPILE!!!

虽然int可以将an自动装箱到Integerint[]但Java 不会
将an自动装箱到Integer[]。您可以编写库函数来执行此操作,但是该语言将不会促进这种转换。

实际上,这是许多关于例如Arrays.asList(anIntArray)“损坏”的困惑的根源,因为返回的List<Integer>实际上不是一个元素,而是返回了a
,而不是返回a List<int[]>

但是性能呢???

Java语言指南/自动装箱中的报价:

将自动装箱和拆箱用于科学计算或其他对性能敏感的数字代码是不合适的。An Integer不能替代an int;
自动装箱和拆箱模糊了原始类型和引用类型之间的区别,但是并不能消除它们。

简而言之,每当自动装箱发生时,性能肯定会受到影响。某些事情可以缓解这种情况,例如,这些类型中内置的缓存机制。这就是为什么您得到以下信息的原因:

    System.out.println(
        ((Integer) 0) == ((Integer) 0)
    );
    // true

    System.out.println(
        ((Integer) 10000) == ((Integer) 10000)
    );
    // false (implementation-specific)

这里发生的是,当0自动 装箱,没有 新的 Integer实际创建的实例:在一定范围内的值被 缓存
为自动装箱宗旨,以有助于提高性能。10000在大多数实现中,它可能不在此范围内,但是某些JVM实现确实允许您在必要时指定缓存范围。

但是我只想获取数组的长度!!!

有很多方法可以帮助您requireInRange使用任何类型的数组。不幸的是,使用Java的原语数组常常意味着很多重复。这意味着提供过载int[]boolean[]byte[]Object[],分别等。

一个更简洁的选择是使用反射,但这有其优点和缺点。一般来说,对于大多数情况而言,反射不是首选的解决方案。

话虽如此,java.lang.reflect.Array确实有一个可以返回_ANY_ 数组长度的方法。它不是类型安全的(就像大多数反射机制一样);传递非数组编译,但在运行时抛出。int getLength(Objectarray)
static __IllegalArgumentException

相关问题

-(受到的启发java.util.Arrays



 类似资料:
  • 问题内容: 为什么第二段代码更快? 问题答案: 自动装箱使用,内部将Integer对象缓存为小整数(默认情况下为-128至127,但是最大值可以使用“ java.lang.Integer.IntegerCache.high”属性进行配置-请参见Integer.valueOf的源代码) ,因此与直接调用不同。因为在调用之前可以快速检查整数值的大小,所以直接调用要快一些(尽管如果您有很多小整数,它会使

  • 如果我有一个泛型参数,我通过模式匹配到基元(如 )来解析该参数,那么自动装箱是否比使用自定义包装器类型便宜?例如 对抗 第一种方法是否提供任何性能优势?如果该方法使用代替,这种情况是否相同: ?

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

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

  • 我正在使用Automapper将我的业务模型映射到ViewModel。 它能工作,但速度很慢。 我有一个包含6893个对象和23个属性的集合(测试环境、生产应该有更多)。 通过循环,需要来映射所有内容。 我试着这样改进它: 用绘制了所有的地图。 所以这没什么帮助。 这是我配置映射器的方式: MyObj: MyViewModel: MyObjOtherObj: MyViewModelOtherObj

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