java: 当 SomeClass 实现 SomeInterface 时从 List<SomeClass> 转换为 List<SomeInterface>

标签 java generics

我脑抽筋了:我有一个 public interface SomeInterface和一个 static private class SomeClass并试图返回 List<SomeInterface>从我的一种方法,但我得到了错误(在下面的 return list; 行):

Type mismatch: cannot convert from List<GenericList1.SomeClass> to
List<GenericList1.SomeInterface>

如何在不创建新列表的情况下解决此问题?

澄清:我不想将列表创建为 List<SomeInterface> (也许是显而易见的解决方案)因为私下里我想维护一个 List<SomeClass>允许将来访问 SomeClass 的方法,而不是公共(public)接口(interface)中的方法。这在下面的示例中没有显示,但在我的实际程序中我需要它。

import java.util.ArrayList;
import java.util.List;

public class GenericList1 {

    public interface SomeInterface
    {
        public int getX();
    }

    private static class SomeClass implements SomeInterface
    {
        final private int x;
        @Override public int getX() {
            return this.x;
        }       
        public SomeClass(int x) { this.x = x; }
    }

    public static void main(String[] args) {
        List<SomeInterface> list = createList(10);
        printList(list);
    }

    private static void printList(List<SomeInterface> list) {
        for (SomeInterface si : list)
            System.out.println(si.getX());
    }

    private static List<SomeInterface> createList(int n) {
        List<SomeClass> list = new ArrayList<SomeClass>();
        for (int i = 0; i < n; ++i)
            list.add(new SomeClass(i));
        return list;
    }
}

最佳答案

您应该将您的方法重新定义为

private static List<? extends SomeInterface> createList(int n) { ...

和其他列表声明类似。这允许您以多态方式处理泛型列表,只要您只从中读取值

(如果您想向列表中添加新元素,则应改用 List<? super SomeInterface>。)

这个习惯用法的缩写 PECS - Producer: Extends/Consumer: Super,由 Josh Bloch 在 Effective Java 第 2 版第 28 项中创造。

正如其他人所指出的,需要这个成语是因为 List<SomeClass> 不是 List<SomeInterface> ,即使 SomeClass implements SomeInterface .其原因在引用文件中有详尽的解释。

关于java: 当 SomeClass 实现 SomeInterface 时从 List<SomeClass> 转换为 List<SomeInterface>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4958913/

相关文章:

java - 返回字节数组时出错

java - Jfreechart索引越界异常

java - 处理过时的域对象(Grails/GORM/Hibernate)引起的并发问题的策略

java - 如何将泛型类型的类作为参数传递?

c# - 泛型和接口(interface)问题

generics - Dart 中带有泛型类型参数的回调

go - 通用 slice 参数和限制为 slice 类型的参数有什么区别?

java - 如何测试从数据库返回给定类型的所有实体的方法?

java - Android 以编程方式设置textcursordrawable,无需反射方法

java - 无界通配符类型 List<?> 和原始类型 List 有什么区别?