[英]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.