簡體   English   中英

將Java泛型與通配符一起使用時,“類型不匹配”

[英]“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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM