首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java错误:不存在类型变量C、T的实例?扩展SubComponent<T>可以转换为C

Java错误:不存在类型变量C、T的实例?扩展SubComponent<T>可以转换为C
EN

Stack Overflow用户
提问于 2022-10-20 18:16:20
回答 4查看 189关注 0票数 3

我有一个相当复杂的阶级结构:

代码语言:javascript
复制
public interface SubComponent<T> {...}

public interface Component<T, C extends SubComponent<T>> {...}

public class Control<T, I extends Component<T, ? extends SubComponent<T>>> {...}

然后,我有两个类,它们将保存控件和每个组件的当前状态,如下所示:

代码语言:javascript
复制
public class ControlState<T, I extends Component<T, ? extends SubComponent<T>>> {
    // The state keeps a reference to the Control,
    // and a map that holds all the states for each component
    private final Control<T, I> control;
    private final Map<Integer, ComponentState<T, ? extends SubComponent<T>>> components = new TreeMap<>();

    // Has a method to add new components
    public void addComponent(int index) {
        // Here I have error on the control parameter
        ComponentState<T, ? extends SubComponent<T>> state = new ComponentState<>(control, index);
        ...
    }
}

public class ComponentState<T, C extends SubComponent<T>> {
    // The component state also has a reference to the Control
    // and the index to retrieve the Component from a List in the Control
    private final Control<T, ? extends Component<T, C>> control;
    private final int index;

    public ComponentState(Control<T, ? extends Component<T, C>> control, int index) {
        this.control = control;
        this.index = index;
    }
}

addComponent(int index)方法中,IDE说:

所需类型:Control<T, ? extends Component<T, C>>

提供:Control<T, I>

但是,既然我是:I extends Component<T, ? extends SubComponent<T>>,我不明白问题在哪里,类型应该是兼容的,我做错了什么?

EN

回答 4

Stack Overflow用户

发布于 2022-10-22 19:19:40

作为解决办法,我决定通过从I类中删除Control信息来简化模型。

因此,结构如下:

代码语言:javascript
复制
public interface SubComponent<T> {...}

public interface Component<T, C extends SubComponent<T>> {...}

public class Control<T> {
    private final List<? extends Component<T, ? extends SubComponent<T>>> components;
}

public class ControlState<T> {
    private final Control<T> control;
    private final Map<Integer, ComponentState<T>> components = new TreeMap<>();

    public void addComponent(int index) {
        ComponentState<T> state = new ComponentState<>(control, index);
        ...
    }
}

public class ComponentState<T> {
    private final Control<T> control;
    private Component<T, ? extends SubComponent<T>> component;
    private int index;
    private final Map<Integer, ? extends SubComponent<T>> subComponents = new TreeMap<>();

    public ComponentState(Control<T> control, int index) {
        this.control = control;
        this.index = index;
    }
}

尽管如此,我还是希望保留这些信息,但我认为我很幸运,这意味着,只要我告诉用户我需要的组件必须是这两个接口的实现,那么在内部,我就拥有了我需要的所有API(由接口公开),以使系统正常工作。

票数 0
EN

Stack Overflow用户

发布于 2022-10-31 13:32:26

我认为这应该能恰当地或不恰当地解决你的目标。因此,这是我的想法。

addComponent()类的ControlState方法中,您试图实例化ComponentState类。现在,在这样做时,可以省略类型参数。在这里,内存分配将像没有类型参数(即非泛型类型)的ComponentState类的对象一样发生,但是,实际对象仍将被称为泛型类型。

此外,您的控件对象也没有实例化(或者为null或正确)。

代码语言:javascript
复制
public class ControlState<T, I extends Component<T, ? extends SubComponent<T>>> {
    // The state keeps a reference to the Control,
    // and a map that holds all the states for each component
    private final Control<T, I> control = null;
    private final Map<Integer, ComponentState<T, ? extends SubComponent<T>>> components = new TreeMap<Integer, ComponentState<T, ? extends SubComponent<T>>>();

    // Has a method to add new components
    public void addComponent(int index) {
        // Here I have error on the control parameter
        ComponentState<T, ? extends SubComponent<T>> state = new ComponentState(control, index);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2022-11-01 10:27:37

编译器不能统一ComponentState.control字段和ComponentState构造函数的通配符,因此类型错误。

您可以通过物化通配符所代表的类型来修复这个问题,以匹配IControlState.state字段中所代表的内容:

代码语言:javascript
复制
public class ComponentState<T, I extends Component<T, ? extends SubComponent<T>>> {
    private final Control<T, I> control;
    private final int index;

    public ComponentState(Control<T, I> control, int index) {
        this.control = control;
        this.index = index;
    }
}

您必须相应地调整components映射的类型。

代码语言:javascript
复制
private Map<Integer, ComponentState<T, I>> components = new TreeMap<>();

现在您可以将ControlState.addComponent实现为

代码语言:javascript
复制
public void addComponent(int index) {
    ComponentState<T, I> state = new ComponentState<>(control, index);
    components.put(index, state);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74144542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档