从列表<MyClass>投射到列表<Interface>

问题描述 投票:0回答:5

我认为我在编写代码时犯了一些错误。 我有一个实现接口的类 MyClass,现在我有一个接口列表通用的方法作为参数。我想通过传递列表来使用我的方法。我无法从一个列表转换到另一个列表(我以为我可以)。那么,我该怎么做才能让我的代码正常工作呢?这是一个例子:

List<MyClass> lista = returnMyClassList();
myMethod((List<Interface>) lista); //this doesn't work

//myMethod signature
public void myMethod(List<Interface> struttura);

感谢您的帮助。

java object interface casting
5个回答
15
投票

对类型使用上限

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
}

2
投票

您可以使用:

public void myMethod(List<? extends Interface> struttura);

为了同时获得

List<Interface>
List<MyClass>


2
投票

您应该使用

public void myMethod(List<? extends Interface> struttura);
。这样你就可以传递任何类型
IS-A
Interface
。您想阅读有关多态性和泛型

的内容

2
投票

List<MyClass>
不是
List<Interface>
的子类型,您会收到错误。
符合java docs

给定两个具体类型 A 和 B(例如 Number 和 Integer),无论 A 和 B 是否相关,MyClass 与 MyClass 都没有关系。 MyClass 和 MyClass 的共同父级是 Object

因此将方法签名更改为

   public void myMethod(List<? extends Interface> struttura){
   }

并调用方法

   List<MyClass> lista = returnMyClassList();      
   myMethod((lista);

1
投票

你不能施展这个,因为你会做出一个你无法兑现的承诺。

当您从

List<MyClass>
转换为
List<Interface>
时,您将获取一个包含 MyClass 类型的多个对象的列表,并将其扩展为一个类型,该类型(除其他外)做出以下承诺:

  1. Interface get(int index)
    - 你可以获得 thpe Interface 的一个元素(没问题)
  2. boolean add(Interface e)
    - 您可以添加 Interface 类型的任何元素(如果它是否是 MyClass 的子类型)(这是一个问题!)

第二点是有问题的,因为底层 List 仍然是

MyClass
的列表,而不是一般意义上的
Interface
的列表。您仍然可以在单独的变量中保存指向基础列表的链接,并可以在该列表上运行
get
。如果您添加了
Interface
类型的对象,但它不是
MyClass
,您可以从
MyClass
获得此 Non-
List<MyClass>

正如所有其他答案和评论所指出的那样,正确的解决方案是类型

List<? extends Interface>
。使用此类型,您仍然可以从列表中获取
Interface
类型的对象(作为方法调用的返回值),但不能将任何内容放入列表中(用作方法调用的参数)。

© www.soinside.com 2019 - 2024. All rights reserved.