集合中的Java通用接口

集合中的Java通用接口,java,generics,Java,Generics,有谁能解释一下,为什么只有在以下代码中创建B时才会出现错误: public class factory { public <T> void createA(List<I<T>> c) { A a = new A(c);//warning here } public <T> void createB(List<I<T>> c) { B b = new B(c);//e

有谁能解释一下,为什么只有在以下代码中创建B时才会出现错误:

public class factory {

    public <T> void createA(List<I<T>> c) {
        A a = new A(c);//warning here
    }

    public <T> void createB(List<I<T>> c) {
        B b = new B(c);//error here: The constructor B(List<I<T>>) is undefined
    }
}

interface I<T> {
}


class B implements I<Integer> {

    public B(List<I<?>> c) {
    }
}

class A<T> implements I<T> {

    public A(List<I<?>> c) {
    }
}
公共类工厂{
公共空间A(列表c){
A=新的A(c);//此处有警告
}
公共空间B(列表c){
B=新的B(c);//此处出错:构造函数B(列表)未定义
}
}
接口I{
}
B类工具I{
公共B(列表>c){
}
}
B类是泛型的,A类不是,但我不知道为什么在这种情况下它很重要

public B(List<I<?>> c) {
}
瞧,向同样的错误问好


瞧,向同样的错误问好。

A
是一个泛型类,这意味着当您单独使用
A
时,它是一个原始类型。使用原始类型时,将关闭其方法和构造函数的所有泛型。例如,将编译以下内容:

A a = new A(new ArrayList<String>());
aa=newa(newarraylist());

B
不是泛型类,因此单独使用
B
不是原始类型,也不会关闭泛型。

a
是泛型类,这意味着单独使用
a
时,它是原始类型。使用原始类型时,将关闭其方法和构造函数的所有泛型。例如,将编译以下内容:

A a = new A(new ArrayList<String>());
aa=newa(newarraylist());

B
不是泛型类,因此单独使用
B
本身并不是原始类型,也不会关闭泛型。

我希望您已经导入了
List
。如果不是,我想这就是错误。你到底收到了什么错误消息?我输入了导入语句,这不是问题。我在评论中写道:“构造函数B(列表)未定义”。嗯,你喜欢做泛型吗?;)您最终真正想要实现什么?
A=newa(c)
是一个原始表达式,因此它会从A类中删除所有泛型,并且不会出现编译错误。如果你正确使用泛型,你会得到同样的错误。我希望你已经导入了
List
。如果不是,我想这就是错误。你到底收到了什么错误消息?我输入了导入语句,这不是问题。我在评论中写道:“构造函数B(列表)未定义”。嗯,你喜欢做泛型吗?;)您最终真正想要实现什么?
A=newa(c)
是一个原始表达式,因此它会从A类中删除所有泛型,并且不会出现编译错误。如果你正确地使用泛型,你会得到同样的错误。但是,为什么这样做呢?只需将此添加到类B:
静态类B实现I{
构造函数仍然相同,但没有更多的编译器错误。现在您会收到“未检查的转换”警告。是的,它可以编译。但是如果要避免未检查的转换,仍然不可能。如果您为另一个方法(
新建a(c))执行正确的构造函数调用
然后你会看到同样的错误。这是我期望的答案-新的A(c)对泛型A类和taht调用构造函数不正确会导致警告而不是错误。谢谢!这个答案不正确。
t
可以通过捕获
,但是捕获只适用于顶级类型参数。因此,如果参数是
I
,并且您传递了一个
I
,那么您可以传递它。但是您不能t将
List
传递到
List但是,为什么这样做呢?只需将其添加到类B:
静态类B实现I{
构造函数仍然相同,但没有更多的编译器错误。现在您得到了“未检查的转换”警告。是的,它可以编译。但是如果你想避免未检查的转换,它仍然是不可能的。如果你对另一个方法进行了正确的构造函数调用(
newa(c)
),那么你会在那里看到相同的错误。这是我期望的答案-newa(c)对泛型A类和taht调用构造函数不正确会导致警告而不是错误。谢谢!这个答案不正确。
t
可以通过捕获
,但是捕获只适用于顶级类型参数。因此,如果参数是
I
,并且您传递了一个
I
,那么您可以传递它。但是您不能t通过
列表
列表