首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java技巧解释

Java技巧解释
EN

Stack Overflow用户
提问于 2009-12-24 12:31:49
回答 1查看 2.1K关注 0票数 7

我正在阅读关于的文章,我遇到了这个主题,我有点困惑。

来自:http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ205

代码语言:javascript
复制
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);
   }
} 

向下滚动几个屏幕..。

代码语言:javascript
复制
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吗?

谢谢。

EN

回答 1

Stack Overflow用户

发布于 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的一个不同的子类,因此添加它可能是错误的

第二代码样本

现在,第二个代码示例是这样一个示例:开发人员对编译时错误感到不快,认为编译器是错误的,并试图强制转换。这样的强制转换可以编译代码,但是可能在运行时在相同的条件下中断(如更高的解释)。

因此,编译器会发出警告,以帮助您理解可能出了问题。

样本问题

对于前面的两个代码示例,如果调用代码写入(对于两个子类NodeANodeB of Node),则可能会发生问题:

代码语言:javascript
复制
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):

代码语言:javascript
复制
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)的示例代码。

代码语言:javascript
复制
public class NodeA extends Node<NodeA>  {
   public NodeA(NodeA parent) {
     super(parent);
   }
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1958182

复制
相关文章

相似问题

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