簡體   English   中英

帶反射的Object.equals()方法的廣義覆蓋的安全性

[英]Safety of Generalized Override of Object.equals() Method With Reflection

我已經厭倦了必須為所有類重寫Object.equals的方法,因此我想出了這種覆蓋方法,如果將其用於項目中的所有類中,則該方法會產生預期的結果。

@Override
public boolean equals(Object anObject){
    if (this == anObject) {
        return true;
    }
    //same class?
    if (anObject.getClass() == this.getClass()) {
        Field[] fields = this.getClass().getFields();
        boolean fieldsEqual = true;
        for (Field field : fields) {
            try {
                fieldsEqual &=
                        field.get(anObject).equals(field.get(this));
            } catch (IllegalAccessException e) { }
        }
        //if fields equal, objects are equal.
        return fieldsEqual;
    }
    //not the same class, so the objects aren't equal
    return false;
}

這樣安全嗎? 未處理的IllegalAccessException使我有些擔心,但是鑒於該方法首先會檢查thisanObject是否是同一類,所以我認為除非在運行時從該類中動態刪除或添加字段,否則不會發生這種情況。 如果可以安全地保存一個異常,這看起來可能是非常方便的代碼段。

StackOverflow的專家對此有何看法?

我不認為嘗試/捕獲IllegalAccessException是一個好主意,它可能會導致您遇到一個非常麻煩的錯誤來進行調試,我會在某個地方登錄。

我通常對equals()使用ApacheCommons equals方法

這確實是一個非常糟糕的主意

請讓IDE為您生成hashCode()equals() ,或使用一個庫,例如@Louis Wasserman建議的Apache Commons Lang EqualsBuilder

除了性能不佳和字段為null (如注釋中已提到的那樣)引發NullPointerException之外,您的代碼還可能遇到無限循環:

public static class Test {

    static class ClassWithUnsafeEqualsMethod {
        @Override
        public boolean equals(Object anObject){
            if (this == anObject) {
                return true;
            }
            //same class?
            if (anObject.getClass() == this.getClass()) {
                Field[] fields = this.getClass().getFields();
                boolean fieldsEqual = true;
                for (Field field : fields) {
                    try {
                        fieldsEqual &=
                                field.get(anObject).equals(field.get(this));
                    } catch (IllegalAccessException e) { }
                }
                //if fields equal, objects are equal.
                return fieldsEqual;
            }
            //not the same class, so the objects aren't equal
            return false;
        }
    }

    static class A extends ClassWithUnsafeEqualsMethod {
        B fieldB;
    }

    static class B extends ClassWithUnsafeEqualsMethod {
        A fieldA;
    }

    public static void main(String... args) {
        A a1 = new A();
        A a2 = new A();
        B b1 = new B();
        B b2 = new B();

        a1.fieldB = b2;
        b2.fieldA = a1;

        a2.fieldB = b1;
        b1.fieldA = a2;

        System.out.println(a1.equals(a2));
    }
}

那里有一個不錯的java.lang.StackOverflowError 試試吧!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM