B extends the original type A Since you are using a raw type, all generic information is deleted, not just a type variable that you did not specify (see Section 4.6 of the Java Language Specifications ). This means that A has the void foo(Object obj) method, while A<SomeType> has the <T> void foo(T obj) method.
If you override a method, it must have the same signature (optional after deleting the erased type of the overridden method). Interestingly, the override method may have another more specific return type. The signatures of your two methods are different (you need to erase the styles in the override method), so your example does not compile.
Erasing the type of reason was implemented as it is, it is backward compatible. The idea was that the new code would only use generics, and only the old code would use raw types. So the goal was not to make the raw types the most convenient (because the new code shouldn't use them), but to make the raw types the most compatible.
Consider, for example, the ArrayList class, which was introduced in Java 2 (long before generics). He had a method public Object[] toArray(Object[] a) . Generalizations were introduced in Java, and the signature of this method can be changed to public <T> T[] toArray(T[] a) (where T not an element type) without difficulty: due to the method of erasing the type, it is implemented for old code, which used (or subclassed) an ArrayList , not an ArrayList<SomeType> method signature remains the same.
Hoopje
source share