为什么NetBean的自动生成等于如此冗长?

时间:2015-10-09 06:53:57

标签: java netbeans

当NetBeans自动生成equals方法时,它采用以下格式:

@Override
public boolean equals(Object obj) {
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    final MyClass other = (MyClass)obj;
    if (!Object.equals(this.field, other.field))
        return false;
    return true;
}

这看起来相当冗长。 Java instanceoffalse值返回null,为什么不将初始测试简化为:

if (!(obj instanceof MyClass))
    return false;

我也不清楚为什么这段代码会在字段比较中明确使用this.field(可能是为了避免混淆)但是出于同样的原因不会使用this.getClass()

NetBean的形式是否有任何优势?

1 个答案:

答案 0 :(得分:4)

instanceof与班级比较之间存在差异。请注意(例如)HashMap实例为instanceof AbstractMap,但AbstractMap的{​​{1}}不应将equals other视为AbstractMap 1}}如果它实际上是HashMapinstanceof测试允许或其任何子类型的实例,因此不是对称的。 equals需要对称性。 (以下示例。)

Netbeans代码似乎相当笨拙并且可以更简洁地编写,但是按照给定的顺序操作是有意义的默认起点。 (虽然我已经包含this检查。)这是一对罕见的类,可以有equal个实例,因此使用getClass进行默认实现是合理的。< / p>

只是提醒我们所有the contract

  • 自反:对于任何非null引用值xx.equals(x)应返回true
  • 对称:对于任何非null引用值xyx.equals(y)应返回true并且仅当y.equals(x)返回true
  • 传递:对于任何非null参考值xyz,如果x.equals(y)返回truey.equals(z)返回true,然后x.equals(z)应返回true
  • 一致:对于任何非null参考值x and y , multiple invocations of x.equals(y)consistently return true {{ 1}}修改了or consistently return等于对象的比较。
  • 对于任何非, provided no information used in参考值nullx应返回x.equals(null)

在我90年代早期的Java时代,我违背了这份合同(不知不觉中),based on the answers to this question,我不是唯一一个。我使用false(和instanceof),如下所示:

super.equals

问题在于它不对称:

class Parent {
    private int foo;
    protected int getFoo() {
        return foo;
    }

    Parent(int f) {
        this.foo = f;
    }

    // ...

    @Override
    public boolean equals(Object obj) {
        // WRONG, see below
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof Parent)) {
            return false;
        }
        return this.foo == ((Parent)obj).foo;
    }
}

class Child extends Parent {
    private int bar;

    Child(int f, int b) {
        super(f);
        this.bar = b;
    }

    // ...

    @Override
    public boolean equals(Object obj) {
        // WRONG, see below
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof Child)) {
            return false;
        }
        return super.equals(obj) && this.bar == ((Child)obj).bar;
    }
}

这违反了合同。