我有这个类,它是我在一个从Java 6移植到Java 8的项目中发现的一些代码的简化:
public class Unification {
final class Box<A> {}
final class MyMap<A, B extends Box<? extends A>> {}
MyMap<?, ?> getMap() {
return new MyMap<Object, Box<Object>>();
}
<A, B extends Box<? extends A>> void setMap(final MyMap<A, B> m) {}
void compileError() {
setMap(getMap());
}
}这是一个很小的例子,仅仅是展示问题,实际的代码更有意义。不过,这个问题似乎相当笼统,因此是一个抽象的例子。核心问题如下:出于某种原因,javac不希望接受一个类型为MyMap<?, ?>的表达式作为setMap()方法的参数,尽管根据我的理解,这应该是很好的类型。
代码使用javac 6编译,没有错误,但是当我使用javac 8时,我得到了这个模糊的错误消息:
C:\System9\KWS_sparse\sourcesNG\Domain\src\uz\Unification.java (21:9) error: method setMap in class Unification cannot be applied to given types;
required: Unification.MyMap<A,B>
found: Unification.MyMap<CAP#1,CAP#2>
reason: inference variable A has incompatible bounds
equality constraints: CAP#1
lower bounds: Object
where A,B are type-variables:
A extends Object declared in method <A,B>setMap(Unification.MyMap<A,B>)
B extends Unification.Box<? extends A> declared in method <A,B>setMap(Unification.MyMap<A,B>)
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends Object from capture of ?
CAP#2 extends Unification.Box<? extends CAP#1> from capture of ?错误消息似乎表明,对于MyMap的第一个类型参数找不到统一,javac无法找到既与CAP#1统一的类型,后者表示setMap()实际参数中的第一个通配符参数,而A则是setMap()形式参数的对应类型参数。尽管在我看来,A和CAP#1应该是完全统一的,但它们都代表通过删除getMap()签名中的实际类型而引入的存在类型。
有人能发现这里出了什么问题吗?javac 6是否错误地接受了此代码?另外,是否有一种不太具有侵入性(与javac 6兼容的)方法来指导javac 8走向正确的统一?
编辑:我尝试在stackoverflow.com. from /质询/23063474/中引入一个变量,但这似乎没有帮助,我得到了相同的编译错误。
EDIT2:澄清了示例代码的“意图”。
EDIT3:将Map重命名为MyMap,显然定义自定义Map类型过于混乱。
发布于 2016-10-27 11:36:58
这个问题可以通过引入中间方法来解决,从而迫使javac在两个阶段进行类型推断。第一个方法只接受一个类型参数,并将第二个类型参数保留为通配符。Javac能够正确地推断出该方法的单一类型参数。然后,第二种和原始的方法能够从提供的参数中正确地推断出第二种类型的参数。
public class Unification {
final class Box<A> {}
final class MyMap<A, B extends Box<? extends A>> {}
MyMap<?, ?> getMap() {
return new MyMap<Object, Box<Object>>();
}
<A> void setMap(final MyMap<A, ?> m) {
doSetMap(m);
}
<A, B extends Box<? extends A>> void doSetMap(final MyMap<A, B> m) {}
void worksFineNow() {
setMap(getMap());
}
}https://stackoverflow.com/questions/40088515
复制相似问题