【问题标题】:Create objects of wrapper classes with java 9使用 java 9 创建包装类的对象
【发布时间】:2018-05-06 04:49:03
【问题描述】:

Java 9 的一个新特性是弃用了包装对象的构造函数。创建新 Wrapper 对象的唯一方法是使用它们的 valueOf() 静态方法。 例如对于 Integer 对象,Integer.valueOf 为 -128 和 127 之间的值实现缓存,并在每次调用时返回相同的引用。

正如Integer 类的 API 所说,“静态工厂 valueOf(int) 通常是更好的选择,因为它可能会产生明显更好的空间和时间性能。”并且 JLS 说“给定相应原始类型的值,通常不需要构造这些盒子类的新实例。推荐的构造替代方法是自动装箱或 valueOf 静态工厂方法。在大多数情况下,自动装箱会起作用,因此类型为基元的表达式可用于需要框类的位置"

但是超出这个范围的值会发生什么? 例如 Integer x = Integer.valueOf(456) 是每次执行类时的新对象?

【问题讨论】:

    标签: java wrapper java-9


    【解决方案1】:

    两者

    Integer x = Integer.valueOf(456);
    

    Integer x = 456;
    

    将始终导致创建Integer 的新实例,因为456 超出了Integer 缓存的范围。

    你可以通过写来测试它

    Integer x1 = Integer.valueOf(456);
    Integer x2 = Integer.valueOf(456);
    System.out.println(x1==x2);
    

    这将打印false

    【讨论】:

    • @silviaDominguez 你说的“总是直奔主题”是什么意思?
    • 对不起,我的意思是堆 ?。我的意思是每次调用都会创建这个对象
    • @silviaDominguez 如果“总是去堆”是指总是创建一个新对象,那是真的(尽管 Javadoc 允许 Java 的实现缓存 -128 到 127 范围之外的值,但是实际上我还没有看到这样的额外缓存)。
    • 这个话题比较复杂。如前所述,允许(甚至鼓励)实现,但不需要为范围外的值实现缓存。但是缓存可以通过两种方式实现,在 Java 代码中实现强制缓存,或者通过 JVM 知道 valueOf 的特殊合约,仅适用于优化代码。但是即使 JVM 在优化时实现了这样的缓存行为,它也会干扰其他优化,例如不做缓存结合逃逸分析允许用常量false替换Integer.valueOf(456)==Integer.valueOf(456)
    【解决方案2】:

    首先为什么要麻烦这些细节 - 比较 Integer 对象的正确方法是使用:

    if (x.intValue() == y.intValue()) 或更好的x.equals(y)

    在任何情况下都不要依赖有一个缓存这个事实,因为这个缓存的上限可以作为一个属性来改变,你可以通过:

    java -XX:+PrintFlagsFinal | grep AutoBoxCacheMax
    

    【讨论】:

    • 如果它很愚蠢,我深表歉意,但我无法将其与当前的问题联系起来。您能否更新一下这与Integer.valueOf 及其缓存范围的关系。
    • @nullpointer 不需要 apoligize,我假设因为你创建了这些对象,你需要在某个时候比较它们,所以你应该不在乎创建了多少个对象如果您正确比较它们。我可能在这里做了太多假设,删除这个可能是正确的......
    • 或者链接或评论 Eran 的答案,这实际上在那里进行了一种比较。您使用的技术在哪里应该可以很好地证明事实?
    猜你喜欢
    • 2016-07-03
    • 2013-01-25
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多