incompatible types and fresh type-variable

后端 未结 2 1052
长情又很酷
长情又很酷 2020-12-03 14:02

I get the following compilation message:

[javac]   ... error: incompatible types
[javac]         exceptionClassHolder = new Holder<>( (new Exception())         


        
相关标签:
2条回答
  • 2020-12-03 14:54
        Holder<? extends Class<? extends Exception>> exceptionClassHolder;
        exceptionClassHolder = new Holder<>( (new Exception()).getClass() );
    

    The reason is that

    1. Because you are not using Exception.class but an Exception object, java thinks ? extends Exception is required.
    2. The same holds for getClass(), again ? extends Class needed, though Class is final.

    Certainly one day this will be simplified.

    0 讨论(0)
  • 2020-12-03 14:59

    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
    0 讨论(0)
提交回复
热议问题