首页 > 解决方案 > 如何返回扩展某些东西的泛型类型 T 的列表

问题描述

我在返回一个扩展了某些东西的泛型类型 T 的列表时遇到了问题。

我有一个名为 A 的基类和两个子类 B 和 C。我想根据某些上下文从方法返回 B 列表或 C 列表,但我无法让编译器同意它。

我的意思是:

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

public class Main {
    public static void main(String[] args) {
        List<B> ls1 = new Main().method1();
        List<C> ls2 = new Main().method2(); // Won't work,
                                            // have to cast to it
        // i.e. List<C> ls2 = (List<C>) new Main().method2();

        System.out.println(ls1);
        System.out.println(ls2);
    }

    <T extends A> List<T> method1() {
        List<B> ls = new ArrayList<>();
        ls.add(new B());
        return ls; // Doesn't work now, compiler error
                   // works if I explicitly cast to it, but says
                   // unsafe or unchecked operation
                   // return (List<T>) ls;
    }

    List<? extends A> method2() {
        List<C> ls = new ArrayList<>();
        ls.add(new C());
        return ls;
    }
}
class A {
}
class B extends A {
}
class C extends A {
}

如您所见,我尝试了通配符和实际类型 T,但它们都没有摆脱编译器错误:“不兼容的类型”。

任何帮助将不胜感激,谢谢。

标签: java

解决方案


修复编译错误

List<C> ls2 = new Main().method2();

你可以做

List<? extends A> ls2 = new Main().method2();

请注意,这不能是List<C>,它是扩展 A 的东西的列表。在这里使用 cast(List<C>)是错误的,因为不能保证method2只返回 C 的列表,例如,它可以是 C 和 B 对象的混合。

Upd:关于出于类似的原因method1进行演员阵容也是错误的。(List<T>) ls想象一下你method1这样实现

<T extends A> List<T> method1() {
    List<C> ls = new ArrayList<>();
    ls.add(new C());
    return (List<T> ) ls;
}

然后在您的main方法中,您可以执行以下操作,编译器不会抱怨

    List<B> ls1 = new Main().method1();
    B b = ls1.get(0);
   

但是您将获得ClassCastException在线运行时B b = ls1.get(0);


推荐阅读