当前位置: 首页 > 知识库问答 >
问题:

Java 原语和原语包装器

慕飞章
2023-03-14

我试图了解Java原语和包装器是如何工作的。让我们考虑以下示例。

Integer sum = 0;
for(int i = 0; i < 10000; ++i) {
    sum += i;
}

由于整数是不可变的和非原语,语句sum=i将编译为以下内容

sum =  new Integer(sum.intValue() + i).

这将创建大约10000个整数对象(每次调用新整数)和sum.intValue()将整数拆箱为int的成本。

我说的对吗?

共有3个答案

司空昊阳
2023-03-14

不,不是那样的。复合赋值运算符< code>E1 op= E2等效于< code>E1 = (T) ((E1) op (E2)),区别在于< code>E1只计算一次。

从JLS第15.26.2节:

形式为E1 op= E2的复合赋值表达式等价于E1 = (T) ((E1) op (E2)),其中T是E1的类型,只是E1只计算一次。

因此,在 Integer 引用和基元类型之间执行二进制操作。在这种情况下,整数引用将被取消装箱,并将执行操作,并且值将再次装箱到整数引用。从 JLS 第 5.6.2 节 - 二进制数字提升:

如果任何操作数属于引用类型,则会对其进行拆箱转换 (§5.1.8)。

因此,不一定会创建新的整数对象。循环中的表达式被计算为:

Integer sum = Integer.valueOf(sum.intValue() + i);

并且< code>valueOf方法可以使用< code>Integer对象的某个缓存值(对于某个范围)。

话虽如此,我希望您在原始代码中不是字面上使用这样的包装器类型,但只是为了理解目的。您不需要使用包装器类型,除非您真的需要它,这将是罕见的情况。

陆高峰
2023-03-14

使用循环时,首选原始类型而不是盒装类型

是的,你是正确的,装箱和拆箱的过程,尤其是在循环中会严重阻碍性能。

但是在你的情况下,你只是循环,你不应该在这里使用盒装原语,而是使用int

公冶昆杰
2023-03-14

不完全是。事实上:

    sum += i;

相当于

    sum = Integer.valueOf(sum.intValue() + i);

对于小整数值,Integer.valueOf(int)将返回一个缓存的整数对象。这意味着您将创建不到10,000个新的整数对象

但“小”通常意味着 -128 到 127 (IIRC) ...所以差异不会很大。

正如Louis Wasserman所指出的,对象分配很便宜,而“夭折”对象的垃圾收集更便宜。尽管如此,您不应该不必要地使用原始包装器,尤其是在这样的代码中。

 类似资料:
  • 问题内容: 扩展和装箱Java原语。 我知道不可能将包装器类从一个扩展到另一个,因为它们不是来自同一继承树。为什么无法将原语扩展为另一种原语类型并自动装箱已扩展的原语? 假定可以将byte参数传递给需要int的方法,为什么不能将以下示例中的字节扩展为int然后装箱为Integer? 在上面的示例中,被编译器接受但被拒绝。 问题答案: 简短答案 Java语言仅支持某种程度的粗心。 更长的答案 我相信

  • 问题内容: 所以今天有人问我这个问题。 该程序将输出什么?它返回true。我回答由于我对自动装箱(和自动装箱)的了解,它将始终打印为false。我的印象是,为Integer分配a = 3将创建一个新的Integer(3),以便an ==将对引用进行评估,而不是原始值。 谁能解释一下? 问题答案: 缓存在-128到127之间的框值。装箱使用方法,该方法使用缓存。超出范围的值不会被缓存,并且始终创建为

  • 两者的计算结果都为false。(顺便说一句,比较是不必要的,因为类不会重写Object中的equals。) 和都是,因为它们可比,没有错误。比较两个具有不同声明的泛型类型的对象是非法的。 在进一步检查时,字段将通过调用包私有的本机方法,如下所示: 除了Java文档对“表示基元类型”的模糊暗示之外,我找不到任何关于这方面的文档。这个领域有什么用处吗?它在包装类本身中没有使用。 (编辑) 是真的。 还

  • 我正在编写一个程序,该程序需要处理具有许多包装数字变量的对象,例如Long,Double,Integer等。如何安全地对这些操作执行数值运算,而不必到处放置空检查? 我认为这是几乎每个Java程序员迟早都必须处理的事情,所以我很惊讶没有数百篇关于这个主题的博客帖子和问题。 我目前的解决方案是通过以下方法过滤所有数字:

  • 主要内容:1. 生产参数,2. 缩进空间,3. 分离空间,4. 忽略行前缀,5. 折叠线在本章中,将了解YAML中语法原语的以下几个方面 - 生产参数 缩进空间 分离空间 忽略的行前缀 折叠线 下面来详细地了解每个方面。 1. 生产参数 生产参数包括一组参数以及在特定生产中使用的允许值范围。 YAML中使用以下生产参数列表 - 缩进 它由字符或表示字符流取决于其中包含的块的缩进级别。 许多生产都参数化了这些功能。 上下文 它由表示,YAML支持两组上下文:块样式和流样式。 样式 它由

  • 本节将覆盖A-Frame原语元素的基本概念以及它们与实体-组件框架的关系。如果你需要了解具体如何使用HTML和原语,可以参阅: 开发指南中构建一个基本场景一节。 HTML A-Frame基于 HTML 和 DOM,对于自定义元素使用一个polyfill。HTML是Web的基石,提供了最容易访问的计算机语言。无需安装或编译构建,创建HTML只需要使用文本, 然后在浏览器中打开该HTML文件。由于A-