Java 实体组件系统 - 推理变量 T 具有不兼容的边界
Java Entity Component System - Inference variable T has incompatible bounds
我正在尝试在 java 中制作自定义实体组件系统,但我在类型擦除方面遇到了一些困难。整个系统功能正常保存一个方法。我希望能够调用一个通用方法 createEntity(Class<? extends Component>... types);
,它接收一个 var args 类型数组,创建一个新的空白实体,并使用反射添加指定类型的新组件。这是我写的方法。
public Entity createEntity(Class<? extends Component>... types){
Entity e = new Entity();
for(Class<? extends Component> type: types){
try {
getParent().getComponentManager().add(type, e.UID, type.newInstance());
} catch (Exception ex) {
ex.printStackTrace();
}
}
INDEX.add(e.UID, e);
return e;
}
这是造成编译错误的行。
getParent().getComponentManager().add(type, e.UID, type.newInstance());
这是ComponentManager
里面的方法class.
public <T extends Component> void add(Class<T> type, int uid, T component){
if(component != null){
ComponentIndex<T> index = getComponentsByType(type);
if(!index.has(uid)){
index.add(uid, component);
component.setParent(this);
}
}
}
Component
class只是一个空接口。
public interface Component{}
我不断从 NetBeans 工具提示中得到的错误类似于
...method add in class ComponentManager cannot be applied to given types;
required: Class, int, T
found: Class, int, Class
reason: inference variable T has incompatible bounds...
鉴于所有组件都将实现 Component
接口,并且所有组件都将具有不带参数的构造函数,我如何使用反射创建基于泛型 Class<?>
的组件?
因此,我在阅读本文后找到了解决此特定问题的方法。 https://docs.oracle.com/javase/tutorial/java/generics/capture.html
问题在于,当使用通配符时,编译器无法保证对象的类型正确,但通过使用通用辅助方法,您可以通过捕获通配符的类型来确保每个元素的类型安全。在这种情况下,这是我使用的辅助方法。
private <T extends Component> void addNewComponentInstance(Class<T> type, int uid){
try {
getParent().getComponentManager().add(type, uid, type.newInstance());
} catch (Exception ex) {
ex.printStackTrace();
}
}
这就是它被夹在通配符方法中的方式。
public Entity createEntity(Class<? extends Component>... types){
Entity e = new Entity();
for(Class<? extends Component> type: types)
addNewComponentInstance(type, e.UID);
INDEX.add(e.UID, e);
return e;
}
此解决方案可以正确编译和运行。
我正在尝试在 java 中制作自定义实体组件系统,但我在类型擦除方面遇到了一些困难。整个系统功能正常保存一个方法。我希望能够调用一个通用方法 createEntity(Class<? extends Component>... types);
,它接收一个 var args 类型数组,创建一个新的空白实体,并使用反射添加指定类型的新组件。这是我写的方法。
public Entity createEntity(Class<? extends Component>... types){
Entity e = new Entity();
for(Class<? extends Component> type: types){
try {
getParent().getComponentManager().add(type, e.UID, type.newInstance());
} catch (Exception ex) {
ex.printStackTrace();
}
}
INDEX.add(e.UID, e);
return e;
}
这是造成编译错误的行。
getParent().getComponentManager().add(type, e.UID, type.newInstance());
这是ComponentManager
里面的方法class.
public <T extends Component> void add(Class<T> type, int uid, T component){
if(component != null){
ComponentIndex<T> index = getComponentsByType(type);
if(!index.has(uid)){
index.add(uid, component);
component.setParent(this);
}
}
}
Component
class只是一个空接口。
public interface Component{}
我不断从 NetBeans 工具提示中得到的错误类似于
...method add in class ComponentManager cannot be applied to given types; required: Class, int, T found: Class, int, Class reason: inference variable T has incompatible bounds...
鉴于所有组件都将实现 Component
接口,并且所有组件都将具有不带参数的构造函数,我如何使用反射创建基于泛型 Class<?>
的组件?
因此,我在阅读本文后找到了解决此特定问题的方法。 https://docs.oracle.com/javase/tutorial/java/generics/capture.html
问题在于,当使用通配符时,编译器无法保证对象的类型正确,但通过使用通用辅助方法,您可以通过捕获通配符的类型来确保每个元素的类型安全。在这种情况下,这是我使用的辅助方法。
private <T extends Component> void addNewComponentInstance(Class<T> type, int uid){
try {
getParent().getComponentManager().add(type, uid, type.newInstance());
} catch (Exception ex) {
ex.printStackTrace();
}
}
这就是它被夹在通配符方法中的方式。
public Entity createEntity(Class<? extends Component>... types){
Entity e = new Entity();
for(Class<? extends Component> type: types)
addNewComponentInstance(type, e.UID);
INDEX.add(e.UID, e);
return e;
}
此解决方案可以正确编译和运行。