java - 扩展另一个泛型类的泛型类的泛型类型参数的绑定不匹配错误
问题描述
我在java中遇到泛型和继承问题。
我想从“createManager”方法实例化一个“ObjectManager”类,该方法可以从给定类型创建实例。这个“ObjectManager”有一些实用方法(例如:“getDescription”)。
这个方法允许我从一个类型中实例化一个“ObjectManager”,然后得到它的描述(这里的哈希)。
如果输入类型可分配给类型“Foo”,我还想为“FooManager”专门化“ObjectManager”,以便我可以覆盖“getDescription”方法。因此,我在“createManager”方法中测试输入的类型,以了解我是创建“ObjectManager”还是“FooManager”。
该代码有效,但我不知道与“new FooManager(type)”对应的输出的泛型类型。在我看来,对于 Eclipse 快速修复,类型应该是 <T> 但这会导致错误:
绑定不匹配:类型 T 不是 FooManager<T> 类型的有界参数 <T extends Foo> 的有效替代品
我的代码:
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;
public class GenericBug {
private GenericBug() {}
public static void main(String[] args) {
ObjectManager<Foo> objectManager1 = createManager(Foo.class);
System.out.println(objectManager1.getDescription());
ObjectManager<Object> objectManager2 = createManager(Object.class);
System.out.println(objectManager2.getDescription());
}
private static <T> ObjectManager<T> createManager(Class<T> type) {
if(Foo.class.isAssignableFrom(type))
return new FooManager<T>(type); //Error: Bound mismatch
return new ObjectManager<T>(type);
}
}
class ObjectManager<T>{
public T val;
public ObjectManager(Class<T> type) {
try {
val = type.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
public String getDescription() {
return "Hash: " + Objects.hash(val);
}
}
class FooManager<T extends Foo> extends ObjectManager<T>{
public FooManager(Class<T> type) {
super(type);
}
@Override
public String getDescription() {
return super.getDescription() + " value: " + val.getVal();
}
}
class Foo{
private double val = Math.random();
public Foo() {}
public double getVal() {
return val;
}
}
所以我的问题是:为什么会出现这个错误?如何在没有警告的情况下修复它?而且,作为奖励,为什么 Eclipse 提供了一个无法编译的解决方案?这是 Eclipse 错误吗?
预先感谢您的回答。
解决方案
问题是您正在混合泛型的编译时安全性和运行时检查isAssignableFrom
。
我不知道更好的方法:
private static <T> ObjectManager<T> createFooManager(Class<T> type) {
if (Foo.class.isAssignableFrom(type)) {
return (ObjectManager<T>) getIt((Class<? extends Foo>) type);
}
return new ObjectManager<>(type);
}
private static <R extends Foo> ObjectManager<R> getIt(Class<R> cls) {
return new FooManager<>(cls);
}
不过,这会引发unchecked warning
。
推荐阅读
- android - 我可以在一个 HTTP 请求中从谷歌距离矩阵 api 获取所有数据吗?
- swift - 带有自动布局的 uiscrollview 的动态内容未按预期工作
- php - 未捕获的 ArgumentCountError。分解意义
- php - PSR-4 自动加载选项没有在我的项目中加载类?
- c# - 脚本任务 C# 中的命令超时
- google-cloud-platform - 是否可以使用 gcloud CLI 启动 GCP 市场条目?
- d3.js - D3 力有向图 - 如何过滤节点和关联链接?
- react-native - 在 React-Native 上实现 Google Cloud Speech-to-Text
- javascript - React Set State From CountDown Child
- ios - 无法在 tabBarControllerVC 上以编程方式设置选项卡栏项目文本