当比较整型对象和常量值时,Java是装箱还是取消装箱整型对象?
根据我读到的内容,“==”是一个引用比较,因此,假设Java将常量装箱以执行对象之间的引用比较是合乎逻辑的。然而,下面的测试代码似乎给出了矛盾的结果。
Integer v1 = 1000;
Integer v2 = 1000;
boolean b1 = v1 == 1000; //True.
boolean b2 = v1 == v2; //False. Proof that 1000 boxes to new object and is not fetched from cache.
那么,使用=
的对象与常量值比较在Java中是如何工作的呢?在这种情况下,操作员是否按值进行比较?
整数池与字符串池相同,但是如果整数对象在-128到127范围内,它会缓存值。因此,当您尝试将此范围内的值分配给包装器对象时,装箱操作将调用Integer.valueOf方法打开它将为已经在池中的对象分配一个引用。
但是,如果将此范围之外的值指定给包装器引用类型Integer。valueOf将为该值创建一个新的整数对象。因此,比较值超出此范围的整数对象的引用将导致错误
那么你的情况呢
Integer v1 = 1000;
Integer v2 = 1000;
boolean b1 = v1 == 1000; //True.
boolean b2 = v1 == v2; // out of range so it will false but if you use 127 instead of 1000 then it will true.
请检查此处的文档
您所谓的“常量值”是int
文本,因此其类型是int
。
JLS 15.21.1说:
如果相等运算符的操作数都是数字类型,或者一个是数字类型,另一个可转换为数字类型(§5.1.8),则对操作数执行二进制数字提升。
在您的v1==1000
测试中,1000
为数字类型,v1
可转换为数字类型,因此执行二进制数字升级。
JLS 5.6.2(二进制数字推广)说:
如果任何操作数是引用类型,它将进行拆箱转换
因此,整数
操作数-v1
-被解压为int
,并执行两个int
s的比较。因此,比较的结果是true
。
当比较两种引用类型时-v1==v2
-不进行拆箱,只比较引用,如JLS 15.21.3所述:
如果等号操作符的操作数都是引用类型或空类型,则该操作是对象相等的。
由于1000
太大,不能由整数
缓存缓存,所以b1
和b2
引用的不是同一个实例,因此比较的结果是false
。
我有这段Java代码: 是否保证在控制台上打印?我的意思是,是通过值(这是我需要做的)还是通过引用标识来比较两个装箱的整数? 另外,如果我将它们转换为未装箱的整数,会有什么不同吗
问题内容: 我有2个数据框。 我想遍历每行,并检查每个名称是否在中。 如果名称在其中,结果应返回1,否则返回0: 谢谢。 问题答案: 采用 在数据框中显示结果 在系列对象中
我们看到在GCC 11.3和Visual Studio 2022中成功编译的C代码在GCC 12.1中存在问题。该代码位于编译器资源管理器:https://godbolt.org/z/6PYEcsd1h(感谢@NathanPierson对其进行了一些简化。) 基本上,模板类决定尝试在const函数中调用非const基类函数,即使const重载可用。这似乎是某种编译器错误,但可能是一些奇怪的新C规则
问题内容: 我已经看到了同时实现Comparable和Comparator的类。这是什么意思?为什么我要一个使用另一个? 问题答案: 下面的文字来自Comparator vs Comparable 可比 可比较的对象能够将自己与另一个对象进行比较。类本身必须实现java.lang.Comparable接口,以便能够比较其实例。 比较器 比较器对象能够比较两个不同的对象。该类不是在比较其实例,而是在
我有一个类赋值,我需要将一个目标排序到一个二叉树节点中,给定一个根,我需要将它与根进行比较,如果目标小于根的值,则将目标作为左子,或者如果目标大于根的值,则将目标作为右子。 我必须使用给定的方法头和参数,我的代码是这样编写的: 返回以下错误: java:109:错误:二进制运算符“<”的操作数类型不正确 我还尝试了compareTo方法,通过尝试类似于 返回以下错误: binarySearchTr
问题内容: 在java中如何比较两个对象是否相等?何时使用equals和hashcode? 问题答案: 理论(针对语言律师和数学倾向者): (javadoc)必须定义一个等价关系(它必须是自反的,对称的和可传递的)。另外,它必须是一致的(如果未修改对象,则它必须保持返回相同的值)。此外,必须始终返回false。 (javadoc)也必须是一致的(如果未根据修改对象equals(),则它必须保持返回