Java 与类型变量不兼容的类型

Java 与类型变量不兼容的类型,java,generics,Java,Generics,谁能告诉我为什么下面的代码无法编译 class A<K> { public <K> A() { } public static <K> A<K> create(Class<K> k) { return new A<K>(); } } public class B<K, V> { A<K> ak; public <K, V

谁能告诉我为什么下面的代码无法编译

class A<K> {

    public <K> A() {
    }

    public static <K> A<K> create(Class<K> k) {
        return new A<K>();
    }
}


public class B<K, V> {

    A<K> ak;

    public <K, V> B(Class<K> klass, V v) {
         ak = A.create(klass);
    }
}
A类{
公共A(){
}
公共静态A创建(k类){
返回新的A();
}
}
公共B级{
ak;
公共B级(klass、V级){
ak=A.create(klass);
}
}
它失败于:

[javac] /home/.../src/B.java:17: error: incompatible types
[javac]         ak = A.create(klass);
[javac]                      ^
[javac]   required: A<K#2>
[javac]   found:    A<K#1>
[javac]   where K#1,V,K#2 are type-variables:
[javac]     K#1 extends Object declared in constructor <K#1,V>B(Class<K#1>,V)
[javac]     V extends Object declared in constructor <K#1,V>B(Class<K#1>,V)
[javac]     K#2 extends Object declared in class B
[javac] 1 error
[javac]/home/../src/B.java:17:错误:不兼容的类型
[javac]ak=A.create(klass);
[javac]^
[javac]必需:A
[javac]发现:A
[javac]其中K#1,V,K#2是类型变量:
[javac]K#1扩展构造函数B(类,V)中声明的对象
[javac]V扩展构造函数B中声明的对象(类,V)
[javac]K#2扩展类B中声明的对象
[javac]1错误
这是一个SSCCE,所以请不要问我想要完成什么。

  • A的构造函数中去掉
  • B的构造函数中去掉
构造函数不需要重新定义类的类型参数。如果这样做,它们将被定义为新的类型参数,隐藏类中的参数(Eclipse警告您这一点)。

  • A的构造函数中去掉
  • B的构造函数中去掉

构造函数不需要重新定义类的类型参数。如果这样做,它们将被定义为新类型参数,隐藏类中的参数(Eclipse警告您这一点)。

相关:顺便说一下,
create
中的
k
参数是无用的
create
可以声明为
publicstaticacreate()
@newacct这里描述了这个习惯用法:但是我承认它在这个示例中可能没有意义,因为它只是一个SSCCE。TBH我并不完全清楚使用该习惯用法是否必要,但有时添加类文字会显式地消除xlint编译器警告。@MarcusJuniusBrutus:当需要在运行时使用类对象时,您会传递该类对象。你在这里不需要它。删除它后,调用它时可能必须显式指定类型参数,因为编译器无法从参数中推断它。相关:顺便说一下,
create
中的
k
参数是无用的
create
可以声明为
publicstaticacreate()
@newacct这里描述了这个习惯用法:但是我承认它在这个示例中可能没有意义,因为它只是一个SSCCE。TBH我并不完全清楚使用该习惯用法是否必要,但有时添加类文字会显式地消除xlint编译器警告。@MarcusJuniusBrutus:当需要在运行时使用类对象时,您会传递该类对象。你在这里不需要它。删除后,调用它时可能必须显式指定类型参数,因为编译器无法从参数推断它。有趣的是,虽然只需要删除B中的构造函数,但A中的构造函数可以保留。我想这是因为A的构造函数签名没有使用K,所以它没有隐藏任何东西。它可以保留,以便上面的代码工作,但它仍然是错误的;)有趣的是,只有在B的构造函数需要删除,在A的构造函数可以保留。我想这是因为A的构造函数签名没有使用K,所以它没有隐藏任何东西。它可以保留,以便上面的代码工作,但它仍然是错误的;)