When overriding equals in Java, why does it not work to use a parameter other than Object?

后端 未结 7 1924
攒了一身酷
攒了一身酷 2020-12-03 18:13

I ran into an interesting behavior recently. It seems that if I override .equals() to take a parameter other than Object, it doesn\'t get called. Can anyone explain to me

相关标签:
7条回答
  • 2020-12-03 18:38

    Notice that the method you are calling is defined in the javadoc for ArrayList<E> as

    boolean contains(Object o)
        Returns true if this list contains the specified element. 
    

    instead of

    boolean contains(E o)
        Returns true if this list contains the specified element. 
    

    Implementation of ArrayList.java:

    private transient Object elementData[];
    
    public boolean contains(Object elem) {
        return indexOf(elem) >= 0;
    }
    
    public int indexOf(Object elem) {
        if (elem == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (elem.equals(elementData[i]))
                    return i;
        }
        return -1;
    }
    

    It uses the equals method defined in the Object superclass since the equals method is not overridden in ArrayList<E>'s implementation.

    When overriding Object equals in java, you should override the Object hashCode method as well.

    Anyway you might want to try the following code:

    class A{    
        public int content;    
        A(){
            this(0);
        }    
        A(int value){
            content = value;
        }   
        public boolean equals(Object obj){
            System.out.println("overriding equals method");
            return this.content == ((A) obj).content;
        }    
        public boolean equals(A a){
            System.out.println("overloading equals method");
            return this.content == a.content;
        }    
        public static void main(String[] args){
            A x = new A(1);
            A y = new A(2);
            Object z  = new A(1);
            System.out.println(x.equals(y));
            System.out.println(x.equals(x));
            System.out.println(x.equals(z));
            //override as z is declared as Object at compile time
            //so it will use methods in class Object instead of class A
            System.out.println(x.equals((Object) y));
            System.out.println(x.equals((Object) x));        
        }   
    }
    //rant: they didn't teach me these in javaschool and I had to learn it the hard way.
    
    0 讨论(0)
提交回复
热议问题