java - 泛型的意外行为

标签 java generics reflection

我在使用 Java 泛型时遇到此错误,但我不明白问题出在哪里;
我有两个这样的类(class):

public abstract class BaseClass{
   ....
}

public class OneClass extends BaseClass{
   ....
}

我有一个 OneClass 的通用存储库:

public class MyRepo<T extends BaseClass>{
   List<T> getElements();
}

然后我有一个应该可以使用泛型的方法:

private MyRepo<OneClass> myRepo;   

public <T extends BaseClass> List<T> myMethod(){
     return myRepo.getElements();
}

除非我强制强制转换为 List(如下所示),否则该方法不起作用:

public <T extends BaseClass> List<T> myMethod(){
   return  (List<T>)  myRepo.getElements();
}

鉴于 OneClass 扩展了 BaseClass,我不明白哪个问题。
感谢您的任何建议。

最佳答案

具有以下形式的方法:

<T> T myMethod()

对实际的 T 进行推断取决于调用站点:

String s = myMethod();
Integer i = myMethod();

考虑到您的场景,人们可以像这样调用您的方法:

List<BaseClass> a = myMethod();
List<OneClass> a = myMethod();

如您所见,这可能是错误的 myMethod实际上可以返回 BaseClass 的另一个子类型(假设 TwoClass )这是正确的转换为 List<OneClass> - 因此您需要将 unsafe 强制转换为 List<T> .

您应该更改 myMethod 的签名到以下之一:

public List<? extends BaseClass> myMethod(){}
public List<BaseClass> myMethod(){}

第一个变体指出这是 BaseClass 的任何子类型的列表另一个只是省略了该信息。

根据您想要实现的目标,检查其他答案或阅读有关 PECS(生产者扩展、消费者 super )或 f-bounded 多态性/自类型以返回具体类型的内容。

关于java - 泛型的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72909534/

相关文章:

java - Google Foobar 数字站

java - PITest 问题 : property 'mainClass' is final and cannot be changed any further

swift - 在 Swift 中扩展 SequenceType

c# - 如何初始化具有构造函数的动态类

c# - 通过反射调用方法时的模糊匹配

java - 为什么 JTextField.setText 会在 changedUpdate() 之前触发 DocumentListener 的 removeUpdate()?

java - 带有 sortKeys 和参数值的 Spring Batch Paging

Java 泛型类型解析

c# - .NET Generic 集合在多线程环境中是否更慢

c# - 如何使用反射调用自定义运算符