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

doc*_*ter 5 java generics

我没有谷歌这个问题.为什么这一行会产生编译错误.

wrapper.doSmth(wrapper.getCurrent());
Run Code Online (Sandbox Code Playgroud)

我正在使用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());
 }
}
Run Code Online (Sandbox Code Playgroud)

错误是:

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
Run Code Online (Sandbox Code Playgroud)

rge*_*man 8

编译错误应该是"捕获?#1与捕获?#2不兼容"的行.这个错误的原因wrapper是a Wrapper<?>.

编译器看到wrapper.getCurrent()返回a Generic<?>,并将wrapper.doSmtha Generic<?>作为参数.但它不会将两个?通配符等同起来,即使我们可以看到它们来自同一个实例并且应该是相同的.

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

public class App<T> {
Run Code Online (Sandbox Code Playgroud)

由于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());
    }
}
Run Code Online (Sandbox Code Playgroud)