确定。让我们说我有以下小界面:
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)
答案 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);
}
}
如果您需要确保T
是GenericsTest
,请使用:
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());
}
}
感谢。