请解释长相等条件

Please explain Long equality condition

考虑以下条件:

if (isCustom() == new Long(1)) {
    System.out.println("ok 1");
}
if (1L == new Long(1)) {
    System.out.println("ok 2");
}

对于以下定义:

static Long isCustom() {
    return 1L;
}

输出为:

ok 2

但是对于

static long isCustom() {
    return 1L;
}

输出为:

ok 1

ok 2

我没明白重点!

在前一种情况下,您将返回一个自动装箱的对象。

在后一种情况下,您将返回一个 long 值。

因为后者只是一个值,代码正在评估 1L 和[具有该值的对象的自动拆箱值] 1L 的等价性。

在前一种情况下,代码正在评估两个对象的身份的等价性,这两个对象的值都是 1L。

在第一种情况下,您有两个 Long 对象,您正在检查它们是否是同一个对象(因为您使用的是 ==,而不是 .equals)。它们不是同一个对象。

在第二种情况下,您将 long 值与 Long 对象进行比较,并且 Long 被拆箱为 long 值。 == 适用于 long 值。

在第一个示例中,您的 isCustom() 方法返回一个 Long -- 1L 被装箱到一个 Long 对象。当您在其上使用 == 运算符时,Java 使用引用相等性。这两个 Long 对象,即使它们表示相同的 long -- 1L -- 是不同的对象,所以条件是 false"ok 1" 不是打印。请注意 certain Longs are not required to be cached like certain Integers.

Note that unlike the corresponding method in the Integer class, this method is not required to cache values within a particular range.

在第二个示例中,您的 isCustom() 方法返回 long -- 此处不执行装箱。 == 运算符然后将 Long(1) 拆箱为 1L 以将其与 isCustom() 返回的 long 进行比较,条件为 true,并且 "ok 1" 被打印出来。

这与 java 基元和盒装类型有关。原始版本 long 由 java ("boxed") 自动转换为对象版本 - Long,反之亦然 "unboxing".

在上面的第一个场景中,您将返回一个盒装原语 Long(即一个对象),并比较该对象是否与您刚刚创建的新对象具有相同的引用。换句话说,您正在比较 Long 和另一个 Long。由于你创建了一个new Long(),对象是不同的,所以if语句returns false和"ok 1"没有被打印出来。

在第二种情况下,您将返回原始类型,并将原始类型与对象进行比较 - 即 longLong。在这种情况下,对象 (Long) 得到 "unboxed" 到一个基本类型,当用 == 比较两个基本类型时,你不是在检查对象引用,而是在检查对象引用检查它们是否具有相同的值。

第二种情况 ("ok 2") 总是将原始 long 与对象 Long 进行比较,因此与上述第二种情况的原因相同。