4
我有兩個類擴展了一個公共基類。基類有一個代碼,對於一個具體的子類,需要知道另一個具體子類的Class
。因此,如果Foo
和Bar
延伸爲Base
,則Foo
的實例需要知道Bar.class
,並且Bar
的實例需要知道Foo.class
。返回類<T>從方法
而且,我很傻,我正在嘗試做正確的事情,並使用Java泛型來確保子類返回一個有效的Java類對象,它擴展了基類。
所以,我嘗試這樣做:
class Base {
abstract protected <T extends Base> Class<T> getOtherClass();
}
編譯器似乎與建設相當快樂。問題出現在實現中。
首先,我想:
class Foo extends Base {
@Override
protected <T extends Base> Class<T> getOtherClass() {
return Bar.class;
}
}
(其中Bar
也延伸Base
)
這抱怨說我在返回值的類型不匹配,這需要一個演員。
然後,我想:
class Foo extends Base {
@Override
protected Class<Bar> getOtherClass() {
return Bar.class;
}
}
現在,編譯器會抱怨需要鑄造在Class<Bar>
。
然後我嘗試:
class Foo extends Base {
@Override
protected Class<Base> getOtherClass() {
return Bar.class;
}
}
現在,我得到都投訴:需要在Class<Base>
和在返回值的演員。
有沒有一種表達方式避免任何強制轉換?
第二個是比較什麼,我釣 - 我會在幾分鐘內接受這一點。出於好奇,你知道爲什麼'''工作和'T'(就像我在問題中使用的那樣)不是?謝謝! – CommonsWare
當您編寫' Class getOtherClass()'時,您告訴編譯器您的方法調用者可以編寫'Class clazz = myFoo.getOtherClass()'。你在說_caller_可以選擇一個「Base」的子類型。這不是你的方法實現所說的。 '?擴展Bar'意味着_implementation_選擇一個子類型並且調用者不知道它是什麼。 (也就是說,我認爲如果你選擇選項2,當你發現自己被迫陷入尷尬的陣容時,你會發現自己已經選擇了希望選擇選項1的選項。) –
啊!好的,這是有道理的。再次感謝!就方案1而言,對於這種特殊情況,我有理由相信方案2將起作用。這是一個用於測試Android O行爲更改的非常簡單的示例應用程序。我實際上並沒有使用'Class' - 我只是將它傳遞給Android(顯式的'Intent'構造函數)。偶爾,我會嘗試推動我對泛型更精細的理解的界限。 :-) – CommonsWare