较短的等于方法与较长的等于方法相同吗?

shorter equals-method the same as longer equals-method?

这两个 equals 方法的行为是否相同?:

("version 1"是eclipse生成的ide,"version 2"是自己制作的。)

版本 1:

public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof CoreSale))
            return false;
        User other = (User) obj;
        return Objects.equals(id, other.id);
    }

版本 2(较短):

public boolean equals(Object obj) {
        // always return false, if not instance of User
        if (obj instanceof CoreSale){
        User other = (User) obj;
        return Objects.equals(id, other.id);
        }
        return false;

    }

obj instanceof CoreSale 是否隐式检查 this == obj 还是我必须在版本 2 中也声明它?

这两段代码应该给出相同的答案,除了一个晦涩难懂的 edge-case1.

它们之间的实质区别是:

  1. this == obj 测试。
  2. 显式 obj == null 测试。
  3. 最终if测试

以相反的顺序处理它们。

我认为您将其写成 obj instanceof Type 还是 !(obj instanceof type) 并不重要。事实上,我希望 JIT 编译器根据分支通常采用的 "direction" 进行优化,并为两种情况生成等效代码。

instanceof 运算符隐式测试 null,因此不需要显式 obj == null 测试。但是,我希望 JIT 编译器能够识别这一点,而不是生成本机代码来两次检查 null。

this == obj 测试正在对假定为频繁发生的案例实施显式 "short circuit"。

  • edge-case 意味着 JIT 编译器将无法插入等效的短路逻辑,如果它不在源代码/字节代码中的话。

  • 不清楚 short-circuit 是否会提高性能。这取决于 actual 这些对象之一与自身进行比较的频率……与这样做的成本。

简而言之,只有this == other测试可能会有所不同(在JIT编译之后),对性能可能有利也可能不利。

但是....如果性能真的很重要,请对其进行基准测试....使用实际数据进行基准测试。


1 - edge-case 发生是因为当 this.idother.id 是同一个对象时 Objects.equals(id, other.id) 可能会抛出异常或给出不正确的答案.对于 id.

的实际运行时类型,这又取决于 Object::equals(Object) 的实际实现