繁体   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