【发布时间】:2018-02-20 15:44:51
【问题描述】:
我正在尝试理解 Java 中的泛型类型,理论上它看起来是可以理解的,但是当我需要将它应用于实际代码时,我遇到了问题。我想声明将返回泛型类型的抽象方法。假设我有一个名为 Magicable 的空接口,并且有 2 个类实现了它:Magican 和 Witch。 现在我想知道这 3 个声明之间有什么区别:
/*1*/protected abstract <T extends Magicable> List<T> getMagicables();
/*2*/protected abstract List<? extends Magicable> getMagicables();
/*3*/protected abstract List<Magicable> getMagicables();
-
在第一种情况下,当我想在扩展抽象类的某个类中实现此方法的主体时遇到问题:
@Override protected List<Magican> getMagicable() {..}我有警告信息:
类型安全:来自 MagicanService 类型的 getMagicable() 的返回类型 List
需要未经检查的转换才能符合来自 MagicableService 类型的 List 。 -
在第二种情况下,我没有这个警告,但是我在上面声明的抽象方法的抽象类中遇到了问题:
public void <T extends Magicable> T getOneFromList() { List<T> list = getMagicables(); //..... }在这种情况下,我在 getMagicables() 调用中出现编译错误:
类型不匹配:无法从 List
扩展为 List 第三种情况会导致上述两个代码位置出现编译错误。我不认为在我的情况下这是否是正确的解决方案。
【问题讨论】:
-
List<Witch> witches = getMagicables(Witch.class);是可行的 - 1.(Class<T> type) .... type.cast(obj) .... -
#1 不太可能是任何人都会使用的一种方法。由于
T的类型参数由调用该方法的代码给出,并且由于我们无法创建T的新实例,因此该方法唯一可以在没有某种未经检查的强制转换的情况下返回一个空列表.因此,为什么例如Collections.emptyList和类似的地方是唯一可以找到这种方法的地方。
标签: java generics inheritance abstract