代码之家  ›  专栏  ›  技术社区  ›  McGeek07

Java实体组件系统-推理变量T具有不兼容的边界

  •  2
  • McGeek07  · 技术社区  · 7 年前

    我试图用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不能应用于给定类型; 必需:Class、int、T 找到:Class,int,Class 原因:推断变量T的边界不兼容。。。

    如何使用反射创建基于泛型的组件 Class<?> 鉴于所有组件都将实现 组成部分 接口,并且所有组件都将有一个没有参数的构造函数?

    1 回复  |  直到 7 年前
        1
  •  0
  •   McGeek07    7 年前

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

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