[英]Java Generics GetThis Trick Explanation
我正在閱讀Java Generics,我遇到了這個主題,我有點困惑。
來自: 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嗎?
謝謝。
在第一個代碼示例中,存在編譯錯誤。 您可以在IDE中自行驗證。
我說: The method add(N) in the type List<N> is not applicable for the arguments (Node<N>)
問題是N是Node的子類型。 N的列表可能是StupidNode的列表,其中StupidNode是Node的子類。 但是當前實例可能不是StupidNode,它可能是Node的不同子類,因此添加它可能是錯誤的 。
現在第二個代碼示例是一個開發人員,他厭倦了他不理解的編譯時錯誤,認為編譯器是錯誤的並試圖強制轉換。 這樣的強制轉換會使代碼編譯,但可能會在相同條件下在運行時中斷 (如上所述)。
因此,編譯器會發出警告,以幫助您了解某些內容可能出錯。
對於前面的兩個代碼示例,如果調用代碼寫入(對於Node
兩個子類NodeA
和NodeB
),則可能會發生此問題:
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
的構造函數中運行的代碼將解釋為(用當前參數NodeB
替換格式參數N
):
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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.