Java使用泛型

mar*_*595 5 java generics

我有一个这样的界面A:

public interface A{
    void myFirstMethod();
    void mySecondMethod();
}
Run Code Online (Sandbox Code Playgroud)

然后我有这个课:

public class MyClass{
    private List<? extends A> elements;

    public MyClass(){
        A obj = new A(){
            @Override
            public void myFirstMethod(){
              //SOME CODE
            }
            @Override
            public void mySecondMethod(){
              //SOME CODE
            }
        };
        elements.add(obj);
    }
}
Run Code Online (Sandbox Code Playgroud)

我以前没有使用泛型(只有类似的东西List<String>...),所以我不明白为什么这段代码不能编译.更准确地说,我elements.add(obj);在方法添加的行上得到的错误不适用于这些参数.

编辑:我已经更改了代码,现在elements.add(obj)编译得很好,但我有另一个问题.

public class MyClass{
    private List<A> elements;

    public MyClass(List<A> elements){
        this.elements = elements;
        elements.add(obj);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试这样做时,它不会编译.

//A1 implements A
List<A1> list = new ArrayList<A1>();
MyClass(list);
Run Code Online (Sandbox Code Playgroud)

我怎么能解决这个问题?

ass*_*ias 9

想象一下,你有两个子类:

class A1 implements A {...}
class A2 implements A {...}
Run Code Online (Sandbox Code Playgroud)

然后你可以写:

List<? extends A> elements = new ArrayList<A1>(); // a list of A1
Run Code Online (Sandbox Code Playgroud)

但是这不应该编译:

elements.add(new A2()); //oops: an A2 is not an A1
Run Code Online (Sandbox Code Playgroud)

因此,除了nulla之外你不能添加任何东西,List<? extends A>因为你不知道它是什么实际的泛型类型.换句话说,? extends A意味着A(或A自身)的特定但未知的子类型.

在你的情况下,List<A>你可能会做你期望的 - 你可以添加一些A1s和一些A2s.

  • @sakura是的,这是行不通的,完全是因为我们正在解释的内容.编译器查看变量`elements`的类型,即`List <?扩展A>`.仅从该类型,编译器不知道列表中元素的确切类型是什么; 它只知道它们是某种未知的类型,扩展了"A".由于它不知道类型到底是什么类型,因此您无法在列表中添加任何内容 - 因为编译器无法判断您尝试放入的内容是否为有效类型.使用`new ArrayList <A>`初始化变量并不重要. (2认同)