![](/img/trans.png)
[英]Generics with Wildcards (Map<? extends A, List<? extends B>>)
[英]new List<A & ? extends B>();
如果您知道如何運行標題行,只需向下滾動到tl; dr或寫一個答案!
我寫了其余的文章以避免XY問題 。 完成后,這不再重要。
我想創建一個使用通用對象(列表,地圖等)的對象。
列表中的對象應滿足2個條件:
mymethod()
(我通過創建一個以該方法作為方法頭的接口來實現) JComponent
MyInterface
並擴展了JComponent(它的子類)。 那就是我出現標題問題的地方: new List<MyInterface extends JComponent);
public abstract class MyClass<X extends JComponent> extends X
,但這是行不通的-出於明顯的原因。 (例如,我必須從超類實現抽象方法,但是如果我現在不知道它是泛型的話)。 我遇到了一個問題,如果可以使此行正常工作,那么很容易做到:
new List<A extends B>();
或由@khelwood引入:new List();
哪里:
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
。
您可以將對象添加到任一視圖中,然后從為上下文提供正確類型的視圖中讀取它們。
自然地,當您添加對象時,編譯器將不會檢查插入的對象是否同時MyInterface
了JComponent
和MyInterface
子類。 那是你的責任。
如果您想要更多(運行時)類型的安全性,可以采用以下方式:
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
,則在運行時列表將檢查插入的對象是否同時MyInterface
了JComponent
和MyInterface
。 閱讀時,您可以像我之前的片段中一樣使用這兩種視圖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.