繁体   English   中英

具有泛型的代码将无法编译

[英]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.doSmthGeneric<?>作为参数。 但它不会将两者等同起来? 通配符,即使我们可以看到它们来自同一个实例并且应该是相同的。

这里的一个解决方案是使App类通用,因此您可以替换通配符。

public class App<T> {

由于GenericWrapper是内部类,因此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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM