Unfortunately, the existing answers don't explain what's going on here. First, the solution is to simply specify the type argument to Holder
:
Holder<Class<? extends Exception>> exceptionClassHolder;
exceptionClassHolder =
new Holder<Class<? extends Exception>>(new Exception().getClass());
The reason your version didn't work is because new Exception().getClass()
returns a Class<? extends Exception>
, where ?
is a wildcard capture (referred to in the compiler error message as CAP#1
). Since you use the "diamond operator" with new Holder<>
, the compiler infers Class<CAP#1 extends Exception>
for T
and so Holder<Class<CAP#1 extends Exception>>
is the type of the created object.
However, this doesn't match your declared type of Holder<Class<? extends Exception>>
. It uses a nested wildcard, which doesn't capture: while CAP#1 extends Exception
is some specific type extending Exception
, the nested ? extends Exception
represents literally any type extending Exception
.
And while Class<CAP#1 extends Exception>
is a subtype of Class<? extends Exception>
, Holder<Class<CAP#1 extends Exception>>
is not a subtype of Holder<Class<? extends Exception>>
because generics aren't covariant, so the assignment fails.
By manually specifying Class<? extends Exception>
for T
, you help the compiler avoid this "trap".
See my similar answers on these posts:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…