我认为我在编写代码时犯了一些错误。 我有一个实现接口的类 MyClass,现在我有一个接口列表通用的方法作为参数。我想通过传递列表来使用我的方法。我无法从一个列表转换到另一个列表(我以为我可以)。那么,我该怎么做才能让我的代码正常工作呢?这是一个例子:
List<MyClass> lista = returnMyClassList();
myMethod((List<Interface>) lista); //this doesn't work
//myMethod signature
public void myMethod(List<Interface> struttura);
感谢您的帮助。
对类型使用上限
Interface
:<? extends Interface>
。
这里有一些可编译的代码,使用 JDK 中的类来说明:
public static void myMethod(List<? extends Comparable> struttura) {}
public static void main(String[] args) {
List<Integer> lista = null;
myMethod(lista); // compiles OK
}
您可以使用:
public void myMethod(List<? extends Interface> struttura);
为了同时获得
List<Interface>
和 List<MyClass>
您应该使用
public void myMethod(List<? extends Interface> struttura);
。这样你就可以传递任何类型 IS-A
Interface
。您想阅读有关多态性和泛型的内容
List<MyClass>
不是 List<Interface>
的子类型,您会收到错误。给定两个具体类型 A 和 B(例如 Number 和 Integer),无论 A 和 B 是否相关,MyClass 与 MyClass 都没有关系。 MyClass 和 MyClass 的共同父级是 Object
因此将方法签名更改为
public void myMethod(List<? extends Interface> struttura){
}
并调用方法
List<MyClass> lista = returnMyClassList();
myMethod((lista);
你不能施展这个,因为你会做出一个你无法兑现的承诺。
当您从
List<MyClass>
转换为 List<Interface>
时,您将获取一个包含 MyClass 类型的多个对象的列表,并将其扩展为一个类型,该类型(除其他外)做出以下承诺:
Interface get(int index)
- 你可以获得 thpe Interface 的一个元素(没问题)boolean add(Interface e)
- 您可以添加 Interface 类型的任何元素(如果它是否是 MyClass 的子类型)(这是一个问题!)第二点是有问题的,因为底层 List 仍然是
MyClass
的列表,而不是一般意义上的 Interface
的列表。您仍然可以在单独的变量中保存指向基础列表的链接,并可以在该列表上运行 get
。如果您添加了 Interface
类型的对象,但它不是 MyClass
,您可以从 MyClass
获得此 Non-List<MyClass>
。
正如所有其他答案和评论所指出的那样,正确的解决方案是类型
List<? extends Interface>
。使用此类型,您仍然可以从列表中获取 Interface
类型的对象(作为方法调用的返回值),但不能将任何内容放入列表中(用作方法调用的参数)。