簡體   English   中英

新列表<A & ? extends B>();</a>

[英]new List<A & ? extends B>();

如果您知道如何運行標題行,只需向下滾動到tl; dr或寫一個答案!

我寫了其余的文章以避免XY問題 完成后,這不再重要。


上下文

我想創建一個使用通用對象(列表,地圖等)的對象。

列表中的對象應滿足2個條件:

  1. 具有mymethod() (我通過創建一個以該方法作為方法頭的接口來實現)
  2. 擴展JComponent

我如何使這項工作:

  1. 我創建了多個類,其中任何一個都實現了MyInterface並擴展了JComponent(它的子類)。 那就是我出現標題問題的地方: new List<MyInterface extends JComponent);
  2. 另一個想法:創建一個抽象類(適合所有​​標准)而不是一個接口。 問題:我需要的具體課程不會擴展同一課程。
  3. 我想到了泛型,就像: public abstract class MyClass<X extends JComponent> extends X ,但這是行不通的-出於明顯的原因。 (例如,我必須從超類實現抽象方法,但是如果我現在不知道它是泛型的話)。

TL;博士

我遇到了一個問題,如果可以使此行正常工作,那么很容易做到:

new List<A extends B>();

或由@khelwood引入:new List();

哪里:

  • A是一個接口(就像我可以聲明一個new List<MyInterface>()
  • 和任何項目擴展? extends B ? extends B (示例:它可以是JTextField或JTextArea或任何他們喜歡的東西, 但它必須是JComponent (的子類) (JComponent = B))

如果您希望能夠創建擴展JComponent並實現您的接口的事物的列表,並將事物添加到此類列表中,則需要定義一個具體的類型,該類型同時實現這兩種:

List<ThatType> list = new ArrayList<>();
list.add(new ThatType());

您可以為此聲明一個類型變量,以便編寫一個通用方法:

<T extends JComponent & YourInterface> void something(T thing) {
  // ...
}

<Something extends SomethingElse>僅適用於類型變量的聲明。

此外,您不會創建Somethings that extends SomethingElse列表:您會創建Somethings列表,並且Somethings是否Something extends SomethingElse取決於如何定義這些類型。

為了更具體一點,您不需要創建new List<String extends Object> :創建List<String> ,而String恰好是Object擴展。

您需要適當地聲明類型變量,例如:

class Foo<B> {
  <A extends B> List<A> list() {
    return new List<>();
  }
}

你說:

另一個想法:創建一個抽象類(適合所有​​標准)而不是一個接口。 問題:我需要的具體課程不會擴展同一課程。

但同時您說它們擴展了JComponent 發生這種情況的唯一可能性是它們都可傳遞地擴展了JComponent 因此,在繼承層次結構的某個點上,存在來自JComponent的直接繼承。

如果這仍然是你的代碼,這是你可以介紹的,而不是另一個類,點JComponent擴展JComponent和實現你的接口。

如果不是這樣,我認為僅使用語法是不可能實現的。

我認為類型系統不能讓您完全按照自己的意願做,並獲得編譯時的類型安全。

一種近似如下:

List<JComponent> componentList = new ArrayList<>();
List<MyInterface> myInterfaceList = (List) componentList;

如果您不介意編譯時警告,則現在在同一列表上有兩個視圖:一個顯示內容為JComponent ,另一個顯示為MyInterface

您可以將對象添加到任一視圖中,然后從為上下文提供正確類型的視圖中讀取它們。

自然地,當您添加對象時,編譯器將不會檢查插入的對象是否同時MyInterfaceJComponentMyInterface子類。 那是你的責任。

如果您想要更多(運行時)類型的安全性,可以采用以下方式:

List rawList = new ArrayList();
List checkedList = Collections.checkedList(rawList, JComponent.class);
List doublyCheckedList = Collections.checkedList(checkedList, MyInterface.class);
List<JComponent> componentList = doublyCheckedList;
List<MyInterface> myInterfaceList = doublyCheckedList;

如果僅插入doublyCheckedList ,則在運行時列表將檢查插入的對象是否同時MyInterfaceJComponentMyInterface 閱讀時,您可以像我之前的片段中一樣使用這兩種視圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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