Java 泛型 GetThis 技巧说明
我正在阅读有关 Java 泛型的内容,并且遇到了这个主题,我对此感到有点困惑。
来自: 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 s 是最好的 避免。
有人能给我一个上面代码抛出 ClassCastException 的例子吗?
谢谢。
I am reading about Java Generics and I came across this topic where I am a bit confused.
From : 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);
}
}
Scrolling lower a couple of screens...
public abstract class Node <N extends Node<N>> {
...
protected Node(N parent) {
this.parent = parent;
parent.children.add( (N)this ); // warning: unchecked cast
}
...
}
Casts whose target type is a type
parameter cannot be verified at
runtime and lead to an unchecked
warning. This unsafe cast introduces
the potential for unexpected
ClassCastException s and is best
avoided.
Could someone give me an example where the above code throws a ClassCastException ?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
第一个代码示例
在第一个代码示例中,存在编译错误。您可以在 IDE 中自行验证。
我的说:
List类型中的方法 add(N) 是不适用于参数 (Node)
问题是 N 是 Node 的子类型。 N 的列表可能是 StupidNode 的列表,其中 StupidNode 是 Node 的子类。但当前实例可能不是 StupidNode,它可能是 Node 的不同子类,因此添加它可能是错误的。
第二个代码示例
现在,在第二个代码示例中,开发人员对他不理解的编译时错误感到恼火,认为编译器是错误的并尝试强制转换。
这样的转换使代码可以编译,但可能在相同条件下在运行时中断(如上文所述)。
因此,编译器会发出警告,帮助您了解可能出现错误。
示例问题
调用代码写入(对于
Node
的两个子类NodeA
和NodeB
),则可能会出现问题:对于前面的两个代码示例,如果 第二行,将在
Node
的构造函数中运行的代码将被解释为(用当前参数NodeB
替换格式参数N
) :如您所见,调用者的第二行将传递一个
NodeA
实例,而Node
的构造函数需要一个NodeB
!因此,错误...更新如评论所要求:子类NodeA(或NodeB)的示例代码。
First code sample
In the first code sample, there is a compile-error. You can verify it yourself in your IDE.
Mine says :
The method add(N) in the type List<N> is not applicable for the arguments (Node<N>)
The problem is that N is a subtype of Node. The List of N might be a list of StupidNode, where StupidNode is a subclass of Node. But the current instance might not be a StupidNode, it could be a different subclass of Node, so adding it could be wrong.
Second code sample
Now the second code sample is one where the developer, annoyed by the compile-time error that he doesn't understand, believes the compiler is wrong and try to force a cast.
Such a cast make the code compile, but could break at runtime in the same conditions (as explained higher).
Therefore, the compiler issues a warning, to help you understand that something could be wrong.
Sample problem
For both previous code samples, the problem could happen if the calling code writes (for two subclasses
NodeA
andNodeB
ofNode
):On the second line, the code that will run in the constructor of
Node
will interpret like (replacing the format parameterN
by the current parameterNodeB
):As you can see, the second line of the caller will pass a
NodeA
instance, while the constructor ofNode
expects aNodeB
! Hence the error...UPDATE as asked by comment : sample code for subclasses NodeA (or NodeB).