通用错误:type ...不适用于参数

时间:2014-10-14 12:10:44

标签: java generics

确定。让我们说我有以下小界面:

public interface MyInterface {
  void interfaceMethod();
}

以及实现此接口的类:

public class GenericsTest implements MyInterface {
  @Override
  public void interfaceMethod() {
    // do something
  }
}

那很简单!

现在我还有另一个使用泛型<T extends MyInterface>的类:

public class AnotherClass<T extends MyInterface> {
  public void doSomethingWith(T obj) {
    System.out.println(obj.toString());
  }
}

现在我不明白这一点。如果我想调用AnotherClass.doSomethingWith(T)方法,如下面的代码片段(此类错误;请参阅下面的编辑):

public class ClassWithError {
  public ClassWithError(AnotherClass<? extends MyInterface> another) {
    another.doSomethingWith(another);
  }
}

我收到以下错误:

The method doSomethingWith(capture#1-of ? extends MyInterface) in the type 
AnotherClass<capture#1-of ? extends MyInterface> is not applicable for the 
arguments (AnotherClass<capture#2-of ? extends MyInterface>)

为什么?

修改

哦,哦!我的样本错了! ... grrrrrr ......抱歉!!

ClassWithError必须是正确的:

public class ClassWithError {
  public ClassWithError(AnotherClass<? extends MyInterface> another, GenericsTest test) {
    another.doSomethingWith(test);
  }
}

然后错误是:

The method doSomethingWith(capture#1-of ? extends MyInterface) in the type 
AnotherClass<capture#1-of ? extends MyInterface> is not applicable for the 
arguments (GenericsTest)

3 个答案:

答案 0 :(得分:2)

AnotherClass#doSomethingWith正在等待T类型的参数,即MyInterface的子类型。在ClassWithError中,您传递的AnotherClass实例不符合此合同。

doSomethingWith签名更改为(示例):

public void doSomethingWith(AnotherClass<?> obj)

或者将ClassWithError的正文更改为(示例):

public ClassWithError(AnotherClass<GenericsTest> another) {
    GenericsTest instance = /* ... */;
    another.doSomethingWith(instance);
}

修改

使用新的代码段,参数化构造函数可能是一个通用的解决方案:

public class ClassWithError {
    public <T extends MyInterface> ClassWithError(AnotherClass<T> another, T test) {
        another.doSomethingWith(test);
    }
}

如果您需要确保TGenericsTest,请使用:

public class ClassWithError {
    public <T extends GenericsTest> ClassWithError(AnotherClass<T> another, T test) {
        another.doSomethingWith(test);
    }
}

甚至简单地说:

public class ClassWithError {
    public ClassWithError(AnotherClass<GenericsTest> another, GenericsTest test) {
        another.doSomethingWith(test);
    }
}

答案 1 :(得分:0)

您试图在泛型类型声明的范围之外使用上限泛型类型。如果没有看到它就有点难以解释,而且我的术语可能有点过时了。

编译器如何知道泛型类型AnotherClass<? extends MyInterface>实际上是什么?

public class ClassWithError {
    public ClassWithError(AnotherClass<? extends MyInterface> another, GenericsTest test) {
        another.doSomethingWith(test);
    }
}

您必须在某处捕获该泛型类型,或明确指定它。

或者:

public class ClassWithError<T extends MyInterface> {
    public ClassWithError(AnotherClass<T> another, GenericsTest test) {
      another.doSomethingWith(test);
    }
}

public class ClassWithError {
    public ClassWithError(AnotherClass<MyInterface> another, GenericsTest test) {
        another.doSomethingWith(test);
    }
}

答案 2 :(得分:0)

请更改您的AnotherClass,如下面的代码。

public class AnotherClass<T extends MyInterfacee> {
  public void doSomethingWith(AnotherClass<? extends MyInterfacee> another) {
    System.out.println(another.toString());
  }
}

感谢。