gpt4 book ai didi

java - 来自 TreeItem 的通配符和泛型

转载 作者:行者123 更新时间:2023-11-29 08:35:24 25 4
gpt4 key购买 nike

我有以下类(class):

class TreeItem<T extends TreeItem<?>>{

private final ObservableList<T> childs;
private T parent;

public void addChild(T unit){
childs.add(unit);
unit.setParent(this);
}

public <T> void setParent(T parent){
this.parent = parent;
}
}

我在 setParent 上收到此消息:

Incompatible types.

Required: T

Found: T

我该如何解决这个问题?

最佳答案

重写这个:

public <T> void setParent(T parent){
this.parent = parent;
}

有了这个:

public void setParent(T parent){
this.parent = parent;
}

此外,我建议删除类名声明中的通配符,因为代码无法编译。

所以替换这个:

class TreeItem<T extends TreeItem<?>>

有了这个:

class TreeItem<T extends TreeItem>

你的类中有一个 final 变量。所以它应该在构造函数或内联中​​初始化。只要您使用泛型变量并且在实例化新对象时解析泛型类型,正确的方法是在构造函数中初始化它,如下所示:

public TreeItem(ObservableList<T> childs) {
this.childs = childs;
}

完成上述建议的更改后,您可能会注意到编译器会警告您消息:Unchecked call to 'setParent(T)'。这意味着编译器不保证代码在运行时是安全的,并且可能发生堆污染。我将用一个例子来说明。以下代码在运行时以 ClassCastException 结束,因为我们将 parent 变量设置为不是 T 的类型(这可能是由于 键入删除)。

class ChildTreeItem<T extends TreeItem> extends TreeItem<T> {
public ChildTreeItem(ObservableList childs) {
super(childs);
}
}



public class TreeItem<T extends TreeItem>{

private final ObservableList<T> childs;
private T parent;

public TreeItem(ObservableList<T> childs) {
this.childs = childs;
}

public void addChild(T unit){
childs.add(unit);
unit.setParent(this);
}

public void setParent(T parent){
this.parent = parent;
}

public T getParent() {
return parent;
}

public static void main(String[] args) {
ChildTreeItem<ChildTreeItem> treeItem =
new ChildTreeItem<>(new ObservableSequentialListWrapper<>(new ArrayList<>()));
TreeItem<ChildTreeItem> parentItem =
new TreeItem<>(new ObservableSequentialListWrapper<>(new ArrayList<>()));

parentItem.addChild(treeItem);
List<ChildTreeItem> itemList = new ArrayList<>();
itemList.add(treeItem.getParent()); //<------------------- Heap pollution

ChildTreeItem childTreeItem = itemList.get(0); //<-------- ClassCastException
}
}

此问题的可能解决方案是不参数化变量 parent 而是使其成为 TreeItem 类型:

public class TreeItem<T extends TreeItem>{

private final ObservableList<T> childs;
private TreeItem parent;

public TreeItem(ObservableList<T> childs) {
this.childs = childs;
}

public void addChild(T unit){
childs.add(unit);
unit.setParent(this);
}

public void setParent(TreeItem parent){
this.parent = parent;
}

public TreeItem getParent() {
return parent;
}
}

希望这对您有所帮助。

关于java - 来自 TreeItem 的通配符和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44457944/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com