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?
- 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.
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.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With