Java泛型问题,修改约束?

标签 java generics

我有两种方法:

   public <T extends Component> void addComponent(BluePrint bluePrint, Class<T> type) throws InstantiationException, IllegalAccessException {
        AddComponent addComponent = addComponentMap.get(type);
        if (addComponent == null) {
            addScriptable(bluePrint, type); <--- fails here
        }
    }

if addComponentMap.get(type); 返回 null,我隐含地知道 T 是 Scriptabe 类型并且需要调用:

    private <T extends Scriptable> void addScriptable(BluePrint bluePrint, Class<T> type) throws InstantiationException, IllegalAccessException {
        scriptableSystems.add(new ScriptableSystem<T>());
    }

问题在于,第二个方法中 T 的上限是可编写脚本的,而第一个方法中 T 的上限是 Component,因此当 addComponent 为 null 时,类型“可能”可能是任何组件。

当 addComponent 为 null 时,我可以以某种方式将约束缩小到 Scritpable 吗?或者以某种方式明确地说,当 addComponent 为 null 时,T 将在调用 addScriptable 之前扩展 Scriptable?

也许值得一提的是,Scriptable 继承自组件。

最佳答案

The issue is that the upper bound for T in the second method is Scriptable and in the first method its Component, therefore type "could" potentially be any component when addComponent is null.

这是正确的,但我想说得更强烈:因为 Scriptable 扩展 Component (而不是相反),类型参数 T方法 addComponent() 中的 可以始终是不受 Scriptable 限制的类型。

Can i somehow narrow the constraint to Scritpable when addComponent is null?

当然。假设您在其他情况下不希望有更严格的限制,这就是强制转换的用途:

public <T extends Component> void addComponent(BluePrint bluePrint, Class<T> type)
        throws InstantiationException, IllegalAccessException {
    AddComponent addComponent = addComponentMap.get(type);

    if (addComponent == null) {
        addScriptable(bluePrint, (Class<? extends Scriptable>) type);
    }
}

您当然会收到有关强制转换的编译器警告。这是正确且正确的,因为该代码取决于编译器无法验证的条件。

Or somehow explicitly say that when addComponent is null T will extend Scriptable, before calling addScriptable?

这正是您通过强制转换所做的所说的。引用类型值的强制转换实际上是一个断言,表明您对该值的运行时类型的了解比编译器可以证明的更多。

此外,如果您希望有与 ClassCastException 不同的 filaure 行为,则可以执行运行时测试:

if (!Scriptable.class.isAssignableFrom(type)) {
    throw new MyChosenException();
}

关于Java泛型问题,修改约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46773076/

相关文章:

java - 为什么不能在有界通配符泛型中拥有多个接口(interface)?

c# - 反射:调用带有泛型列表的方法作为结果

java - Eclipse 显示推断通用类型参数 - 希望删除此警告而不抑制它

在 C 中检查对 _Generic() 选择的支持

java正则表达式找到一个字符串,将其添加到数组中,然后替换原来的字符串

java - Hibernate 关系映射/加速批量插入

java - AsyncInvoker 不释放线程

c# - 推断类型的模板和隐式类型转换有什么问题?

Java:charAt 转换为 int?

java - 将上传的图像从各种格式转换为 JPEG