两个不同的Java对象始终相等,无论字段值如何。

huangapple go评论70阅读模式
英文:

Two different Java objects are always equal regardless of fields value

问题

我定义了以下类:

@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder

public abstract class A {
    private Enum myEnum;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder

public class KA extends A {
    private MyPackage pck;
    private String field1;
    private String field2;
}

我使用以下代码对它们进行了测试:

KA ka1 = new KA();
KA ka2 = new KA();
System.out.println("Object equal: " + ka1.equals(ka2));

对于KA,无论使用无参数构造函数还是带有完全不同参数的构造函数,我都会得到它们是相等的。

我希望KA使用Object类的默认equals方法,该方法比较对象的内存地址。

这里有什么问题?

英文:

I have classes defined like below:

@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder

public abstract class A {
    private Enum myEnum;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder

public class KA extends A {
    private MyPackage pck;
    private String field1;
    private String field2;
}

I tested them with the following code:

KA ka1 = new KA();
KA ka2 = new KA();
System.out.println("Object equal: " + ka1.equals(ka2));

For KA, either no-arg constructor or constructor with totally different arguments, I would get they are equal.

I want KA to be using the default equal method of Object class which is comparing the object memory addresses.

What is wrong here?

答案1

得分: 1

假设您正在使用Lombok的@Data注解,它会基于被注解类中的字段生成一个.equals()方法。即,equals方法不包括子类的字段。请阅读此注解的文档:https://projectlombok.org/features/Data

英文:

Assuming that you're using lombok's @Data, it generates an .equals() method for your class based on the fields within the annotated class. I.e. the equals-method does not include the fields of the child class. Read the documentation of the annotation here: https://projectlombok.org/features/Data

答案2

得分: 0

KA类继承其equals方法自A,因为A使用基于字段的相等性,这是由于@Data所导致的。具体来说,如果两个实例具有相同的myEnum值并且属于完全相同的类,它将返回true

为了获得与Object.equals相匹配的基于标识的相等行为,您需要重写KA中的相等性方法以获得所需的行为:

public class KA extends A {
    private MyPackage pck;
    private String field1;
    private String field2;

    @Override
    public boolean equals(Object o) {
        return this == o;
    }

    @Override
    public int hashCode() {
        return System.identityHashCode(this);
    }
}

请注意,这将满足equals所需的等价关系。Lombok的equals实现会小心确保不同类的对象是不相等的。因此,KA永远不会等于非KAA,反之亦然。

英文:

Class KA inherits its equals method from A, which uses a field-based equality due to @Data. Specifically, it returns true if the two instances have the same value for myEnum and are exactly the same class.

In order to get the same identity-based equality behavior matching Object.equals, you'll need to override the equality methods in KA to have the desired behavior:

public class KA extends A {
    private MyPackage pck;
    private String field1;
    private String field2;

    @Override
    public boolean equals(Object o) {
        return this == o;
    }

    @Override
    public int hashCode() {
        return System.identityHashCode(this);
    }
}

Note that this will satisfy the equivalence relation required by equals. Lombok's equals implementation is careful to ensure that objects of different classes are unequal. Therefore, a KA will never equal a non-KA A, and vice versa.

huangapple
  • 本文由 发表于 2023年2月27日 14:28:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75577342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定