I am trying to understand why the compiler treats objects (using wildcard generics) being inline declared differently then objects being first set to an variable.
See the following example:
public class SillyTest{
interface A<T extends B> {}
interface B {}
@Test
public void m() {
Class<?> b1 = A.class.getClass();
Class<? extends B> bb1 = (Class<? extends B>) b1; // works fine
Class<? extends B> bb2 = (Class<? extends B>) A.class.getClass(); // doesn't compile
Class<? extends B> bb3 = (Class<? extends B>)(A.class.getClass()); // also doesn't compile
}
}
Note: Depending on your compiler configuration you may have to add an @SuppressWarnings("unchecked")
Annotation.
Why does the compiler handles these two cases different? I would expect that due to compiler inlining these calls should be equivalent anyway. Apart from the fact that this is an uncheckted cast (which may or may not work) getClass()
returns an Class<?>
, so I do not see a reason why this should be handled differently.
CodePudding user response:
Since Class<A>
doesn't extend B
, your two last statements are obviously false, and that can be determined at compile time. b1
on the other hand, is of type Class<?>
, so it is not known at compile time whether ?
does extends B or not. There needs to be a runtime check.