Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding a method using type erasure

Tags:

java

jvm

generics

Today I stumbled upon something interesting. Assume the following Java 6 class:

public class Ereasure {

    public Object get(Object o) {
        return null; // dummy
    }

    public  static class Derived<T> extends Ereasure{
        // (1)
        @Override
        public Object get(T o) {
                return super.get(o);
        }
        // (2)
        /*
        @Override
        public Object get(Object o) {
                return super.get(o);
        }*/

    }
}

If you try to compile the above example, the compiler says Ereasure.java:9: method does not override or implement a method from a supertype @Override If you remove the @Override annotation(which should not be necessary!), it says Ereasure.java:8: name clash: get(T) in Ereasure.Derived and get(java.lang.Object) in Ereasure have the same erasure, yet neither overrides the other This is a bit contradictional, since T should erease to Object and therefor override the parent classes get method.

If you leave (1) unannotated and uncomment (2) so (1) overloads (2) it would not work either. Compiler output:

Ereasure.java:15: get(T) is already defined in Ereasure.Derived
  public Object get(Object o) {

As a conclusion, T is being ereased to Object, but cannot override the parent get Method.

My question is now, why dooesn't at least one of the examples compile?

like image 821
user3001 Avatar asked Aug 31 '11 14:08

user3001


People also ask

What are the two 2 types of Erasure?

- Erasure is a type of alteration in document. It can be classified as chemical erasure and physical erasure. - There are many chemicals which are able to invisible the ink such as oxalic acid, sodium hydrochlorite etc.

What is type erasure in Java?

Type erasure is a process in which compiler replaces a generic parameter with actual class or bridge method. In type erasure, compiler ensures that no extra classes are created and there is no runtime overhead.

Why Java uses type erasure?

Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.

What is type erasure and when would you use it?

Type-erasure simply means "erasing" a specific type to a more abstract type in order to do something with the abstract type (like having an array of that abstract type).


2 Answers

You can see in the example below why it is impossible to do what you want:

public class Erasure {

   public void set(Object o) {
      return;
   }

   // method overloading: (which is valid)
   public void set(String s) {
      return;
   }

   public static class Derived<S> extends Erasure {

      // Oops... which one am I supposed to override?
      // (It would actually be overloading if S was a concrete type
      // that is neither Object nor String.)
      @Override
      public void set(S o) { // does not compile
         super.set(o);
      }
   }
}

The solution to your problem is that Erasure should be a parameterized class.

like image 78
toto2 Avatar answered Sep 20 '22 21:09

toto2


At a simple guess the compiler does not use the generic view when calculating overloads which of course would not make sense, because sometimes T might be Object other times its another type. The overridding would then become dependent on a moving target T which is downright wrong, especially if there were multiple methods all called "get" but with different single parameter types. In such a case it just wouldnt make sense and at a guess they chose to just keep things simple.

like image 30
mP. Avatar answered Sep 22 '22 21:09

mP.