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() ); } } ```

Original source

Related problems