我正在阅读关于的文章,我遇到了这个主题,我有点困惑。
来自:http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ205
public abstract class Node <N extends Node<N>> {
private final List<N> children = new ArrayList<N>();
private final N parent;
protected Node(N parent) {
this.parent = parent;
parent.children.add(this); // error: incompatible types
}
public N getParent() {
return parent;
}
public List<N> getChildren() {
return children;
}
}
public class SpecialNode extends Node<SpecialNode> {
public SpecialNode(SpecialNode parent) {
super(parent);
}
} 向下滚动几个屏幕..。
public abstract class Node <N extends Node<N>> {
...
protected Node(N parent) {
this.parent = parent;
parent.children.add( (N)this ); // warning: unchecked cast
}
...
}目标类型为类型参数的
强制转换不能在运行时进行验证,并导致未经检查的警告。这种不安全的强制转换引入了可能出现意外的ClassCastException,最好避免。
有人能给我举个例子,上面的代码抛出一个ClassCastException吗?
谢谢。
发布于 2009-12-24 13:12:14
第一代码示例
在第一个代码示例中,有一个编译错误.您可以在IDE中自己验证它。
我说:The method add(N) in the type List<N> is not applicable for the arguments (Node<N>)
问题是N是节点的一个子类型。N的列表可能是StupidNode的列表,其中StupidNode是Node的子类。但是当前的实例可能不是StupidNode,它可能是Node的一个不同的子类,因此添加它可能是错误的。
第二代码样本
现在,第二个代码示例是这样一个示例:开发人员对编译时错误感到不快,认为编译器是错误的,并试图强制转换。这样的强制转换可以编译代码,但是可能在运行时在相同的条件下中断(如更高的解释)。
因此,编译器会发出警告,以帮助您理解可能出了问题。
样本问题
对于前面的两个代码示例,如果调用代码写入(对于两个子类NodeA和NodeB of Node),则可能会发生问题:
Node<NodeA> root = new NodeA<NodeA>(null);
// code needs a change, to be able to handle the root, that has no parent
// The line with parent.children will crash with a NullPointerException
Node<NodeB> child = new NodeB<NodeB>(root);在第二行中,在Node构造函数中运行的代码将解释为:(将格式参数N替换为当前参数NodeB):
public abstract class Node <NodeB> {
private final List<NodeB> children = new ArrayList<NodeB>();
private final NodeB parent;
protected Node(NodeB parent) {
this.parent = parent;
parent.children.add(this); // error: incompatible types
}
// ...
}如您所见,调用方的第二行将传递一个NodeA实例,而Node的构造函数则需要一个NodeB!因此错误..。
按照注释的要求更新:子类NodeA (或NodeB)的示例代码。
public class NodeA extends Node<NodeA> {
public NodeA(NodeA parent) {
super(parent);
}
}https://stackoverflow.com/questions/1958182
复制相似问题