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