[英]“Type mismatch” when using Java generics with wildcard
我在Java中使用泛型時遇到了一個奇怪的問題。 泛型對我來說很新,但是我想我了解基本知識。
請看一下這段代碼:
private void drawQuadtreeBoxes_helper(QuadTree<?> node) {
if (node == null)
return;
Vector3 min = node.bbox.min;
Vector3 max = node.bbox.max;
// Draw the boxes (...)
if (node.hasChildren()) {
Array<QuadTree<?>> children = node.getChildren(); // ERROR HERE
for (QuadTree<?> child : children) {
drawQuadtreeBoxes_helper(child);
}
}
}
因為存儲在四叉樹結構內部的對象類型與該方法無關,所以我對方法簽名使用通配符,因此該方法可以應用於各種QuadTree。
方法getChildren()返回該節點的四個子節點,存儲在稱為Array的集合類(Array的實現 )內。 我確定getChildren()的返回類型確實是Array<QuadTree<?>>
(即使Eclipse在工具提示中也這樣說),但是我仍然在這行上得到一個錯誤,告訴我:
cannot convert from Array<QuadTree<capture#6-of ?>> to Array<QuadTree<?>>
這里是有趣的部分:當我向Eclipse請求如何解決此問題的建議時,這是建議之一:
Change type of 'children' to 'Array<QuadTree<?>>'
但是它已經是這種類型了! 更好:當我單擊此建議時,Eclipse將此行更改為:
Array<?> children = node.getChildren();
當然,這會破壞以下所有代碼。
這里到底發生了什么? 有人可以啟發我嗎?
問題在於方法不知道它是相同的 QuadTree<?>
( ?
可能在同一調用中引用不同的類型)。
解決的辦法是“類型”的方法,它鎖定在QuadTree<?>
(因此?
),以在整個方法中的相同的類型。
private <T extends QuadTree<?>> void drawQuadtreeBoxes_helper(T node) {
if (node == null)
return;
Vector3 min = node.bbox.min;
Vector3 max = node.bbox.max;
// Draw the boxes (...)
if (node.hasChildren()) {
Array<T> children = node.getChildren(); // ERROR HERE
for (T child : children) {
drawQuadtreeBoxes_helper(child);
}
}
}
?
仍然表示“任何東西”,但現在卻是相同的 “任何東西”。
除了Bohemian的答案,我想指出的是,您仍然可以擁有所需的簽名(沒有人知道您正在使用此“ T”類型參數,因為這是實現細節。
您可以通過使用原始類型簽名的包裝器方法來實現,該方法使用T調用通用方法。該調用由於捕獲而起作用。
private void drawQuadtreeBoxes_helper(QuadTree<?> node) {
drawQuadtreeBoxes_helper_private(node);
}
private <T extends QuadTree<?>> void drawQuadtreeBoxes_helper_private(T node) {
// code here ...
}
當然,由於示例中的方法是私有的,因此您可能不必費心做所有這一切。 但是,如果它是一個公共API,則最好這樣做,以抽象出T不必要的實現細節。
如果您不在乎QuadTree中的類型參數,則只需從代碼中刪除所有地方:)只需嘗試以下代碼,編譯器就會認為它可以:
private void drawQuadtreeBoxes_helper(QuadTree node) {
if (node == null)
return;
Vector3 min = node.bbox.min;
Vector3 max = node.bbox.max;
// Draw the boxes (...)
if (node.hasChildren()) {
Array<QuadTree> children = node.getChildren();
for (QuadTree child : children) {
drawQuadtreeBoxes_helper(child);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.