[英]Code with generics won't compile
我没有谷歌这个问题。 为什么这一行会产生编译错误。
wrapper.doSmth(wrapper.getCurrent());
我正在使用java 7。
public class App {
Wrapper<?> wrapper;
class Generic<T>{
}
class Wrapper<T>{
Generic<T> current;
public void doSmth(Generic<T> generic){
}
public Generic<T> getCurrent(){
return current;
}
}
public void operation(){
wrapper.doSmth(wrapper.getCurrent());
}
}
错误是:
Error:(25, 24) java: method doSmth in class App.Wrapper<T> cannot be applied to given types;
required: App.Generic<capture#1 of ?>
found: App.Generic<capture#2 of ?>
reason: actual argument App.Generic<capture#2 of ?> cannot be converted to conf.App.Generic<capture#1 of ?> by method invocation conversion
编译错误应该是“捕获?#1与捕获?#2不兼容”的行。 这个错误的原因是wrapper
是一个Wrapper<?>
。
编译器看到wrapper.getCurrent()
返回Generic<?>
,而wrapper.doSmth
将Generic<?>
作为参数。 但它不会将两者等同起来?
通配符,即使我们可以看到它们来自同一个实例并且应该是相同的。
这里的一个解决方案是使App
类通用,因此您可以替换通配符。
public class App<T> {
由于Generic
和Wrapper
是内部类,因此T
仍然在范围内,因此您不再需要为它们声明泛型类型参数。
Wrapper wrapper;
class Generic{
}
class Wrapper{
Generic current;
public void doSmth(Generic generic){
}
public Generic getCurrent(){
return current;
}
}
public void operation(){
wrapper.doSmth(wrapper.getCurrent());
}
}
可能是捕获助手的工作 。
public void operation() {
operationImpl(wrapper);
}
private static <T> void operationImpl(Wrapper<T> wrapper) {
wrapper.doSmth(wrapper.getCurrent());
}
无需其他更改。 帮助器捕获wrapper
的类型,因此我们可以确保getCurrent
返回与doSmth
接受的类型相同的类型。
发生此错误的原因是每次引用带有通配符的类型时,都会假定表达式中的特定点(称为“捕获”)具有不同的类型:
Wrapper<?> wrapper = ...;
// each capture for T is assumed distinct from each other
// vvvvvvv vvvvvvv
wrapper.doSmth(wrapper.getCurrent());
引用指向同一实例的事实与指定捕获的方式无关。 编译器不需要考虑到这一点,也可能发生类似的事情
Wrapper<?> wrapper = new Wrapper<String>();
wrapper.doSmth((wrapper = new Wrapper<Float>()).getCurrent());
其中T
可以改变中间表达。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.