【问题标题】:Java Entity Component System - Inference variable T has incompatible boundsJava 实体组件系统 - 推理变量 T 具有不兼容的边界
【发布时间】:2018-07-25 17:20:26
【问题描述】:

我正在尝试在 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 类中的方法。

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 类只是一个空接口。

public interface Component{}

我从 NetBeans 工具提示中不断收到的错误类似于

...类 ComponentManager 中添加的方法不能应用于给定类型; 必需:类,int,T 找到:类,int,类 原因:推理变量 T 的边界不兼容...

鉴于所有组件都将实现Component 接口,并且所有组件都将具有不带参数的构造函数,我如何使用反射来创建基于通用Class&lt;?&gt; 的组件?

【问题讨论】:

  • 不确定,但如果您是 extending 接口,那么它仍然是 interface
  • 我的意思是所有组件都将实现Component 接口。
  • 所以你不应该使用implements 而不是extends 吗?
  • 因此我在编辑中所做的语义更改^ “鉴于所有组件都将实现组件接口”
  • 你用什么版本的Java编译?自 Java 8 以来,类型推断发生了变化,我无法在 Intellij IDEA 中使用 Java 9 重新创建它。

标签: java components entity system


【解决方案1】:

所以,在阅读了这篇文章后,我找到了解决这个特定问题的方法。 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;
}

此解决方案可以正确编译和运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多