如何在Java中正确比较两个整数?

2022-08-31 05:16:11

我知道,如果你将一个盒装的基元整数与一个常量进行比较,例如:

Integer a = 4;
if (a < 5)

a将自动取消装箱,比较将起作用。

但是,当您比较两个盒装并希望比较相等或小于/大于时,会发生什么情况?Integers

Integer a = 4;
Integer b = 5;

if (a == b)

上面的代码会导致检查它们是否是同一个对象,还是在这种情况下会自动取消装箱?

怎么样:

Integer a = 4;
Integer b = 5;

if (a < b)

?


答案 1

否,== 整数、多头等之间将检查参考相等性 - 即

Integer x = ...;
Integer y = ...;

System.out.println(x == y);

这将检查是否引用相同的对象而不是相等的对象。xy

所以

Integer x = new Integer(10);
Integer y = new Integer(10);

System.out.println(x == y);

保证打印 。“小”自动装箱值的实习可能会导致棘手的结果:false

Integer x = 10;
Integer y = 10;

System.out.println(x == y);

由于拳击规则(JLS第5.1.7节),这将打印。它仍然被使用引用相等,但引用确实是相等true

如果装箱的值 p 是介于 -128 和 127(包括 -128 和 127)之间的整数文本(§3.10.1),或者布尔文本 true 或 false (§3.10.3),或者介于 '\u0000' 和 '\u007f' (§3.10.4) 之间的字符文本,则让 a 和 b 是 p 的任意两次装箱转换的结果。a == b 总是这样。

就我个人而言,我会使用:

if (x.intValue() == y.intValue())

if (x.equals(y))

正如你所说,对于包装器类型(等)和数值类型(etc)之间的任何比较,包装器类型值是无框的,并且测试应用于所涉及的基元值。IntegerLongintlong

这是二进制数字提升的一部分(JLS 第 5.6.2 节)。查看每个操作员的文档,了解它是否适用。例如,从 和 (JLS 15.21.1) 的文档:==!=

如果相等运算符的操作数都是数值类型,或者一个是数值类型,另一个是可转换为数值类型 (§5.1.8),则对操作数执行二进制数值提升 (§5.6.2)。

和 for 、 和 (JLS 15.20.1<<=>>=)

数值比较运算符的每个操作数的类型必须是可转换为基元数值类型的类型 (§5.1.8),否则会发生编译时错误。对操作数执行二进制数值提升 (§5.6.2)。如果操作数的提升类型为 int 或 long,则执行有符号整数比较;如果此提升类型为浮点型或双精度型,则执行浮点比较。

请注意,在两种类型都不是数值类型的情况下,这些都不被视为一部分。


答案 2

==仍将测试对象相等性。然而,很容易被愚弄:

Integer a = 10;
Integer b = 10;

System.out.println(a == b); //prints true

Integer c = new Integer(10);
Integer d = new Integer(10);

System.out.println(c == d); //prints false

具有不等式的示例将起作用,因为它们未在对象上定义。但是,通过比较,仍将检查对象相等性。在这种情况下,当您从盒装基元初始化对象时,将使用相同的对象(对于 a 和 b)。这是一个不错的优化,因为基元框类是不可变的。==