我试图了解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的成本。
我说的对吗?
不,不是那样的。复合赋值运算符< 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对象的某个缓存值(对于某个范围)。
话虽如此,我希望您在原始代码中不是字面上使用这样的包装器类型,但只是为了理解目的。您不需要使用包装器类型,除非您真的需要它,这将是罕见的情况。
使用循环时,首选原始类型而不是盒装类型
是的,你是正确的,装箱和拆箱的过程,尤其是在循环中会严重阻碍性能。
但是在你的情况下,你只是循环,你不应该在这里使用盒装原语,而是使用int
不完全是。事实上:
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支持两组上下文:块样式和流样式。 样式 它由
问题内容: 我碰到了Java的一个奇怪角落(对我来说似乎很奇怪) o / p:是 o / p:错误 我观察到,如果我们将任意两个值(如我在示例中提到的float和double)与OR 进行比较,例如3.5、234.5、645.0,则输出为即两个值相等,否则输出为相等。 甚至我都试着做方法,但是没有运气。我错过了什么吗? 问题答案: 看一下每位计算机科学家应该了解的浮点数。 将无限多个实数压缩为有限