Java – incompatible types and fresh type variables
I get the following compilation message:
[javac] ... error: incompatible types [javac] exceptionClassHolder = new Holder<>( (new Exception()).getClass() ); [javac] ^ [javac] required: Holder<Class<? extends Exception>> [javac] found: Holder<Class<CAP#1>> [javac] where CAP#1 is a fresh type-variable: [javac] CAP#1 extends Exception from capture of ? extends Exception [javac] 1 error
In my opinion, according to the information, everything should be right Cap #1 does extend exceptions So how should the above news be understood? Sscce is as follows (not released initially, because I want to know the error message itself in general):
class Holder<T> { public T t; public Holder(T t) { this.t = t; } } public class FooMain { public static void main(String args[]) throws Exception { Holder<Class<? extends Exception>> exceptionClassHolder; exceptionClassHolder = new Holder<>( (new Exception()).getClass() ); } }
Solution
Unfortunately, the existing answers do not explain what happened here First, the solution is to simply specify the type parameter of the holder:
Holder<Class<? extends Exception>> exceptionClassHolder; exceptionClassHolder = new Holder<Class<? extends Exception>>(new Exception().getClass());
Your version doesn't work because of the new exception () Getclass() returns a class , where? Is a wildcard capture (called cap#1 in the compiler error message) Since you use the "Diamond operator" of the new "holder", the compiler infers that the class < cap#1 extends exception > for T and so on, and the holder < class < cap#1 extends exception > > is the type of object created
However, this is different from the holder type you declared > It uses a nested wildcard, which does not catch: while the exceptions of cap#1 extension are some specific types of extension exceptions, nested? An extension exception represents the type of any extension exception
The < cap#1 extension exception > is a subtype extension exception of class, and the holder < class < cap#1 extension exception > > is not the holder < class > allocation failed because genetics are't covariant
By manually specifying class for T, you can help the compiler avoid this "trap"
See my similar answers on these posts:
> Java: Wildcard Types Mismatch Results in Compilation Error > Bounded-wildcard related compiler error