At first glance I thought the following makes sense:
interface Test<T> {
T getValue(T n);
}
class Impl implements Test<Integer>{
public Integer getValue(Integer n){
return n;
}
}
And it compiles properly so everything seems A-OK.
But then I thought about it some more, in the context of erasure, and it seems to me that the Test interface gets erased to this:
interface Test {
Object getValue(Object n);
}
So how is Impl still able to implement Test?
javac
actually creates bridge methods for this:compiles to
Note:
Synthetic
andBridge
are not real annotations, but the compiled class files do tag these methods as "synthetic" and "bridge".By using these bridge methods, Java ensures that if you have an
Impl
, you can callImpl#getValue(Integer)Integer
(if you know that it actually has typeImpl
), or you can call the "generic"Test#getValue(Object)Object
, if you only know that it's aTest<?>
.