[英]Java generics: Use this type as return type?
我正在努力使API盡可能用戶友好。
讓我們:
class B extends A {}
class A {
A setX(){ ...; return this; }
}
現在這個
B b = new B().setX();
無效,必須鑄造:
B b = (B) new B().setX();
是否有一種方法在A
使用泛型使編譯器知道“this”類型並接受第一種方式 - 沒有強制轉換並且沒有在使用的地方傳遞類型參數? (即不是new B<B>().setX()
,這很難看。)
我知道為什么Java需要在這種情況下重新輸入。 請不要解釋說明setX()
返回A. 我知道。 我在問仿制葯能否解決這個問題。
對於那些仍然想告訴我“這就是靜態類型如何工作”和“甚至泛型不能幫助解決”的人,請考慮這個有效的Java代碼:
Map<String, String> map = new HashMap(){{ put( "foo", new RuntimeException() );
String foo = map.get("foo"); // ClassCastException!!
因此,您可以看到泛型DO允許您在代碼中沒有出現實際類型轉換的情況下獲得CCE。
這就是為什么我希望泛型允許擺脫顯式類型轉換的原因。
此外,IIRC C ++允許這樣做 。
我在這里將部分答案復制到另一個問題 ,解釋了對所謂的“自我類型”的渴望以及Java中的解決方法。
而不是寫作
foo.doA();
foo.doB();
很多人寧願寫作
foo.doA().doB();
不幸的是,該語言並不直接支持方法鏈接,即使它正在成為越來越渴望的功能。 解決方法是讓doA()
返回foo
。 它有點臟但可以接受。
但是,如果foo
位於類型層次結構中,則解決方法將被破壞
class Bar
Bar doA()
class Foo extends Bar
Foo doB();
foo.doA().doB(); // doesn't compile, since doA() returns Bar
所以有些人要求一種特殊的“自我類型”來解決這個問題。 假設有一個關鍵字This
代表“自我類型”
class Bar
This doA()
foo.doA().doB(); // works, doA() returns the type of foo, which is Foo
方法鏈接似乎是“自我類型”的唯一用例,因此語言可能永遠不會引入它(最好直接支持方法鏈接)
人們發現泛型為這個問題提供了一種解決方法
class Bar<This>
This doA()
class Foo extends Bar<Foo>
Foo has a method "Foo doA()", inherited from Bar<Foo>
這是A extends B<A>
模式最常用的用例。 這是一個孤立的解決方法/技巧。 它在A和B之間的關系中沒有添加語義。
約束This
也是一種流行的做法
class Bar<This extends Bar<This>>
這是丑陋和無用的,我強烈建議反對它。 只需使用“This”作為約定來表示它的用途。
如果你真的不喜歡演員,你可以讓B
覆蓋這個方法
@Override
public B setX() {
super.setX();
return this;
}
在A類中試試這個:
public <T extends A> T setX() {
return (T) this;
}
你可以像這樣使用它
B b = new B().setX();
問題是方法setX()
返回類A
對象,並且您嘗試將其寫入類B
的對象。 反過來也可以不進行強制轉換( A a = new B();
),但是這樣你必須強制轉換它,因為語句B b = new B().setX();
類似於B b = new A();
這是做不到的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.