5
Class<? extends MyClass> cls = (Class<? extends MyClass>) Class.forName(className);
someMethod(cls); // someMethod expects a Class<? extends MyClass>

The above statement gives a warning "Type safety: Unchecked cast from Class<capture#5-of ?> to Class<? extends MyClass>".

Class<?> cls0 = Class.forName(className);
if (cls0 instanceof Class<? extends MyClass>) {
    Class<? extends MyClass> cls = (Class<? extends MyClass>)cls0;
    someMethod(cls);
}

This time I get an error, because of type erasure...

Class<?> cls0 = Class.forName(className);
if (MyClass.class.isAssignableFrom(cls0)) {
    Class<? extends MyClass> cls = (Class<? extends MyClass>)cls0;
    someMethod(cls);
}

This time I know that the cast is safe, but the compiler doesn't, and still gives the warning. (If you ask me, the compiler is being a bit thick here.)

Is there any way to avoid this warning (except for SuppressWarnings)?

Adam Burley
  • 5,551
  • 4
  • 51
  • 72
  • you "checked" before you cast, so it's not exactly "unchecked cast". you know better than the compiler in this case, so just tell it to chill:) - related - http://stackoverflow.com/questions/16611053/generics-oddity-i-can-insert-a-long-value-into-a-mapstring-string-and-it-co/16612897#16612897 – ZhongYu May 26 '15 at 18:18
  • The important thing to remember is that `Class` is special in that it represents its own type parameter. – biziclop May 26 '15 at 19:05
  • So your last code snippet and `@SuppressWarnings` is the way to go here or one step better is [this](http://stackoverflow.com/a/30466702/574479), which does exactly the same thing that your code does. – biziclop May 26 '15 at 19:09

1 Answers1

4

The correct way to do what you want is:

Class.forName(className).asSubclass(MyClass.class);
jtahlborn
  • 52,909
  • 5
  • 76
  • 118
  • Thanks - and funnily enough, the [OpenJDK source for this method](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Class.java#Class.asSubclass%28java.lang.Class%29) uses `@SuppressWarnings` and `isAssignableFrom` just like in my third code snippet above. I didn't know this before posting my question. I find it hilarious that Java generics is so broken that they have to use `@SuppressWarnings` in their own source code. – Adam Burley May 27 '15 at 08:45