[英]Some questions about Java Generics
假设我有以下接口和实现类:
interface Foo<FooType extends Foo<FooType>> {
FooType copy();
}
class Bar implements Foo<Bar> {
public Bar copy() {
return new Bar();
}
}
如果我尝试这样做:
public <FooType extends Foo<FooType>> FooType getFoo() {
return new Bar();
}
我收到编译错误“类型不匹配:无法从 Bar 转换为 FooType”。 为什么?
我可以通过像这样重写函数来“修复”这个问题:
@SuppressWarnings("unchecked")
public <FooType extends Foo<FooType>> FooType getFoo() {
return (FooType) new Bar();
}
但是假设我有一个这样的功能:
public <FooType extends Foo<FooType>> void printFoo(FooType foo) {
System.out.println(foo.toString());
}
如果我尝试这样做:
printFoo(getFoo());
我收到以下编译错误:
Bound mismatch: The generic method printFoo(FooType) is not applicable
for the arguments (Foo<Foo<FooType>>). The inferred type Foo<Foo<FooType>>
is not a valid substitute for the bounded parameter <FooType extends Foo<FooType>>
哇? getFoo() 的返回类型实际上与 printFoo() 的参数类型相同!
这些错误还是我错过了什么?
问题是FooType
可以是任何东西,而不仅仅是Bar
。 您可以返回FooType
的实例。
例如,如果你有class NotBar implements Foo<NotBar> {
那么
obj.<NotBar>getFoo();
现在FooType
的实际参数是NotBar
。
问题是,使用您声明的方法:
public <FooType extends Foo<FooType>> FooType doGetFoo()
这是一个泛型方法,它指出我应该取回我指定的泛型类型。 例如,如果我有一个呼叫Bat
延伸Foo<Bat>
和我的呼叫instance.<Bat>doGetFoo()
它应该返回的一个实例Bat
相反,它是硬编码的,返回的实例Bar
以不一定是泛型中指定的类的实例。 如果你删除通用如下你应该没问题:
public Foo<?> doGetFoo(){
return new Bar();
}
知道了! 感谢meriton 回答了这个版本的问题:
我需要通过printFoo(getFoo())
部分逐步编译编译器:
public <FooType extends Foo<FooType>> void doPrint() {
FooType foo = getFoo();
printFoo(foo);
}
然后调用doPrint()
。
然后一切正常。
所以,我猜即使是“为什么?” 中间可能是我缺乏理解(感谢 Bhesh 清理了那部分),“WAT?” 最后是合理的,因为这确实应该起作用......例如,出于某种原因,在上面的代码中内联“foo”的变量定义是不行的......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.