繁体   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