我有两种方法:
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
}
}
如果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的上限是Scriptable,而在第一种方法中它是Component,因此键入&#34;可以&#34;当addComponent为null时,可能是任何组件。
当addComponent为null时,我可以以某种方式将约束缩小到Scritpable吗?或者以某种方式明确地说当addComponent为null时,T会在调用addScriptable之前扩展Scriptable吗?
值得一提的是,Scriptable继承自组件。
答案 0 :(得分:1)
问题是第二种方法中T的上限是 脚本和第一种方法中的Component,因此键入 当addComponent为null时,“可能”可能是任何组件。
这是正确的,但我更强烈地说:因为Scriptable
扩展Component
(而不是相反),在方法{{1}中输入参数T
总是是一个不受Scriptable限制的类型。
当addComponent为时,我可以以某种方式将约束缩小到Scritpable 空?
不确定。假设你不想在其他情况下更严格的约束,那就是施法:
addComponent()
您当然会收到关于演员表的编译器警告。这是正确的,因为该代码取决于编译器无法验证的条件。
或者以某种方式明确地说当addComponent为null时,T会 在调用addScriptable之前扩展Scriptable?
这正是你做通过施法所说的。具有引用类型值的强制转换实际上是一个断言,您可以更多地了解该值的运行时类型,而不是编译器可以证明的。
此外,如果您的灯丝行为与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);
}
}
不同,则可以执行运行时测试:
ClassCastException
答案 1 :(得分:0)
如果您无法缩小地图中类的泛型类型,您仍然可以进行投射。为了更安全,您可以使用Class.isAssigneableFrom
,它是类的实例(而不是对象):
public static void main(String[] args) {
Map<String, Class<? extends Number>> map = new HashMap<>();
Class<? extends Number> someNumberClass = map.get("Double");
if (Integer.class.isAssignableFrom(someNumberClass)) {
acceptInteger((Class<Integer>) someNumberClass);
}
}
public static void acceptInteger(Class<Integer> c) { }
这甚至不需要空检查,并且可以适用于addComponent
不为空的情况。在您的示例中,您将执行以下操作:
if (Scriptable.class.isAssignableFrom(type)) { // add the null check if necessary
addScriptable(bluePrint, (Class<Scriptable>) type);
}