4

I completely get this question Method has the same erasure as another method in type and the answer to it. Please can anyone help me understand the below?

Trying hard to digest, why the 2nd code snippet below gives compiler error?

Code 1: Compiles fine

class Parent {
    public void set(Collection<Integer> c) { }
}

class Child extends Parent {
    public void set(Collection<Integer> c) {}
}

Code 2: Compiler Error at set method in Child class.

class Parent {
    public void set(Collection<?> c) { }
}

class Child extends Parent {
    public void set(Collection<Integer> c) {}
}

Compiler Error is

Name clash: The method set(Collection) of type Child has the same erasure as set(Collection) of type Parent but does not override it

Community
  • 1
  • 1
mtk
  • 13,221
  • 16
  • 72
  • 112
  • is it because the parent is nullable, and your child isn't? –  Oct 27 '14 at 11:31
  • possible duplicate of [Type erasure, overriding and generics](http://stackoverflow.com/questions/502614/type-erasure-overriding-and-generics) – Joe Oct 27 '14 at 12:29

2 Answers2

2

Because your code in the first example is overriding the method from the parent, you end up with one set method on the child object:

 public void set(Collection<Integer> c) {}

Which is obviously fine.

In your second example you are not overriding the method on the super-type (since the over-riding method is not a sub-signature of the method you're trying to override). Therefore it must be possible for both methods to exist on the child type.

//from parent:
public void set(Collection<?> c)

//from child:
public void set(Collection<Integer> c)

Which, after type erasure, isn't possible:

//from parent:
public void set(Collection c)

//from child:
public void set(Collection c)
StuPointerException
  • 7,117
  • 5
  • 29
  • 54
  • That is actually OP's question. If both end up like `public void set(Collection c) ` then there should be no error. Right ? – Suresh Atta Oct 27 '14 at 11:44
  • I've edited my answer to add more clarity. They do both end up as set(Collection c), however since in the second case it's not an overriding method it appears twice on the child object. – StuPointerException Oct 27 '14 at 11:54
0

Java uses type erasure. So after type erasure, the two methods look identical, however, the methods do not override each other, so you'd end up with two different methods that have an identical signature - this is what gives the name clash. That's not allowed, because at runtime it would be unknown which one it should be used.

If you wish to override the method, you could use a helper method with wildcard capturing as follows:

class Parent {
    public void set(Collection<?> c) { }
}

class Child extends Parent {
    public void set(Collection<?> c) {
        setHelper(c);
    }

    public <T> void setHelper(Collection<T> c) {
        // use T instead of Integer in body of code
    }
}

Note: this code will work if you pass it a collection that contains Integers, however, this code will also work for a collection that contains any type as well, not limited to (nor checked for) Integers.

Smiley
  • 190
  • 1
  • 12