Can somebody explain me, why a simple <T>
in my interface destroys type safety at compile time? See following example:
public class GenericsMain {
public static void main(String[] args){
A someA = new A() {
@Override
public List<String> listOfStrings() {
return Arrays.asList("A");
}
};
B someB = new B() {
@Override
public List<String> listOfStrings() {
return Arrays.asList("B");
}
};
List<Long> listOfLong = null;
//listOfLong = someA.listOfStrings(); // compile error (expected)
listOfLong = someB.listOfStrings(); // NO COMPILE ERROR. Why !?
for(Long l : listOfLong){ // here I get ClastCastException of course.
System.out.println(l);
}
}
interface A{
List<String> listOfStrings();
}
interface B<T>{
List<String> listOfStrings();
}
}
Also interesting is, that if a type for <T>
is specified, the compiler complains again correctly. So it looks like generics also affect non-generic method declarations!?
B<Integer> someBOfInteger = null;
listOfLong = someBOfInteger.listOfStrings(); // compiler complains correctly
Update after correct answers:
So if one needs to extend a type with generics it is better to really create a subclass/subinterface and add the generic type in the subclass. So in the above example one could add a generic method to A by
interface C<T> extends A {
T genericMethod(T p);
}
Also as indicated by the referenced question, it is a good idea to use the compiler flag:
javac -Xlint:unchecked ....