incompatible types and fresh type-variable
generics, java
Solution
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:
- Java: Wildcard Types Mismatch Results in Compilation Error
- Bounded-wildcard related compiler error
Problem
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 ``` It would seem to me that the according to the message all should be correct. `CAP#1` indeed extends Exception. So how should the above message be understood? SSCCE below (initially not posted since I was hoping to understand the error message itself in the general case): ``` 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() ); } } ```
Related problems
- What is PECS (Producer Extends Consumer Super)?
- Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?
- Multiple wildcards on a generic methods makes Java compiler (and me!) very confused
- Java: Wildcard Types Mismatch Results in Compilation Error
- Bounded-wildcard related compiler error