簡體   English   中英

Java泛型:使用此類型作為返回類型?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM