This compiles:
public static void main(final String... args) {
final Fred fred = new Fred();
final Integer i = fred.get(Integer.class);
}
public interface Bob {
<T> T get(final Class<T> type);
}
public static class Fred implements Bob {
@Override
public <T> T get(final Class<T> type) {
return type.cast(null);
}
}
This does not:
public static void main(final String... args) {
final Fred fred = new Fred();
final Integer i = fred.get(Integer.class);
}
public interface Bob {
<T> T get(final Class<T> type);
}
public static class Fred<Q> implements Bob {
@Override
public <T> T get(final Class<T> type) {
return type.cast(null);
}
}
But this does:
public static void main(final String... args) {
final Fred<?> fred = new Fred();
final Integer i = fred.get(Integer.class);
}
public interface Bob {
<T> T get(final Class<T> type);
}
public static class Fred<Q> implements Bob {
@Override
public <T> T get(final Class<T> type) {
return type.cast(null);
}
}
And this does:
public static void main(final String... args) {
final Fred fred = new Fred();
final Integer i = ((Bob) fred).get(Integer.class);
}
public interface Bob {
<T> T get(final Class<T> type);
}
public static class Fred<Q> implements Bob {
@Override
public <T> T get(final Class<T> type) {
return type.cast(null);
}
}
What is going on here?
UPDATE: Thanks to Bob Lee in the comments, I see what is going on. Using a class-level raw type results in the methods of that class also being treated as raw types, even though the type parameters of the class and method are separate. (NB — this does not apply to static
methods, only instance methods.)