Java 不兼容的类型和新类型变量

Java 不兼容的类型和新类型变量,java,generics,Java,Generics,我得到以下信息: [javac] ... error: incompatible types [javac] exceptionClassHolder = new Holder<>( (new Exception()).getClass() ); [javac] ^ [javac] required: Holder<Class<? extends Exception>> [j

我得到以下信息:

[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

Holder不幸的是,现有的答案无法解释这里发生了什么。首先,解决方案是简单地将type参数指定给
Holder

Holder<Class<? extends Exception>> exceptionClassHolder;
exceptionClassHolder =
        new Holder<Class<? extends Exception>>(new Exception().getClass());

Holder@Bohemian好的,我将首先尝试在一个更简单的情况下复制它+1作为扩展解释。但我不明白为什么您会说“首先,解决方案是简单地将类型参数指定给Holder”。为什么?在Java7中,它应该由编译器推断。无论如何,如果不是,它应该在编译时崩溃,这不是OP的问题。它是由编译器推断的,但不是“正确的”-推理将构造函数参数优先于变量。它在编译时确实失败了。我只查看了Object.getClass()的返回类型,而没有查看文档的文本,这确实表明返回的实际类型是
Class@JBNizet没错,很抱歉没有在前面详细说明。我仍然更喜欢Joop Eggen的解决方案,因为它使使用钻石操作符成为可能,并且丑陋只隐藏在一个地方。但是,我接受你的回答,因为我的问题的措辞是为了获取关于理解消息和错误的信息,而不是关于应用什么解决方案的信息。这是不必要的-请参阅我的答案。@PaulBellora我的解决方案与菱形运算符(如所问)一起工作。阅读您的优秀答案(my+1),您会得到这样的印象:钻石操作员不应该工作。正如您所看到的,我有编程语言/编译器构造的背景,所以您可能会更详细一些。谢谢。您是对的,菱形运算符在分配给
HolderI时起作用。我想指出,使用
Holder
    Holder<? extends Class<? extends Exception>> exceptionClassHolder;
    exceptionClassHolder = new Holder<>( (new Exception()).getClass() );
Holder<Class<? extends Exception>> exceptionClassHolder;
exceptionClassHolder =
        new Holder<Class<? extends Exception>>(new Exception().getClass());