![](/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.