zchen
zchen

Reputation: 119

Both methods have same erasures

I have read similar questions, and know generic erasures will cause this error IN SAME CLASS. But I cannot understand why following code dont work.

I designed some examples. And found many many things confusing.

public static class Father<S> {

    public void foo(Set<String> s) {...}

    public void bar(S s) {...}

    public void baz(String s) {...}
}


public static class Son<E> extends Father {

    public void foo(Set<String> s) {...} **// error**

    public void bar(E e) {...} **// error**
 // public void bar(Object e) {...} // This works

    public void baz(String s) {...}
}


public static class Daughter<E> extends Father<T> {

    public void foo(Set<String> s) {...} **// error**

    public void bar(Object e) {...}

    public void baz(String s) {...} **// error**
}

As you can see, I got several erros. Here is my questions:

  1. Let's focus on Father and Son. Why does baz work, while foo does not?
  2. Let's see bar in Son. Why Object e works, while E e fails? I think E will be erased to Object?
  3. Let's see Daughter, why baz fails, comparing to Son?

Please anyone tell me why this occurs? Many thanks! (I know I should not use raw classes. But why this causes error? )

Upvotes: 2

Views: 597

Answers (2)

davidxxx
davidxxx

Reputation: 131346

Here :

public class Son<E> extends Father {

You are using a raw Father in the definition of the class extending.
It is a bad practice.
You should rather write :

public class Son<E> extends Father<E> {

Using raw types has also consequences in terms of inheritancy.
From the JLS :

The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.

and :

The supertype of a class may be a raw type. Member accesses for the class are treated as normal, and member accesses for the supertype are treated as for raw types.

As a consequence, Son doesn't consider generics in the parent class.
For Son , this inherited method :

public void foo(Set<String> s) {
}

is indeed bound as :

public void foo(Set s) {
}

So, the child and the parent methods have the same erasure but the child method doesn't override the parent method as you don't use exactly the same type :

public void foo(Set<String> s) {...} **// error**

If you override in this way to be conform to the raw version of the Father :

public void foo(Set s) {...} 

it will compile.

For bar() method with generics, it is exactly the same thing.

This :

public void bar(E e) 

will be bound as :

public void bar(Object e) 

And you get the same problem...

I will not explain all the points as I don't think that it is helpful.
What you get is the result of bad practices.

The morale is you have not to use raw types for class designed to work with generics as it may create serious side effects on their initial intention and usage of the class.

This

public static class Son<E> extends Father {

should be :

public static class Son<E> extends Father<E>  {

And this :

public static class Daughter<E> extends Father<T> {

should be :

public static class Daughter<E> extends Father<E> {

Upvotes: 1

Eran
Eran

Reputation: 393811

The issue is that Son<E> extends a raw Father class.

Therefore foo and bar of the Son class don't override

public void foo(Set<String> s) {}

public void bar(S s) {}

of the Father class, which (after erasure) become

public void foo(Set s) {}

public void bar(Object s) {}

and have the same erasure of the methods of the same name in the Son class.

Changing the declaration of Son to

public static class Son<E> extends Father<E>

will resolve the errors.

The baz method has no issues since it has no generic arguments, so baz of the sub-class overrides baz of the base-class.

In your Daughter class, it's not clear where T is coming from. If you change T to E, all the errors go away.

Oh, and void bar(Object e) works in the original example since it overrides void bar(S s) of Father (due to the fact the Son extends a raw Father).

Upvotes: 1

Related Questions