[英]new List<A & ? extends B>();
If you know how to run the title line, just scroll down to tl;dr or write an answer! 如果您知道如何运行标题行,只需向下滚动到tl; dr或写一个答案!
I wrote the rest of the text to avoid the XY problem . 我写了其余的文章以避免XY问题 。 It doesn't matter anymore, when this is done.
完成后,这不再重要。
I want to create an object that takes a generic (List, Map, whatever). 我想创建一个使用通用对象(列表,地图等)的对象。
The objects within the list should fullfill 2 criterias: 列表中的对象应满足2个条件:
mymethod()
(which I realized from creating an Interface having this as a method head) mymethod()
(我通过创建一个以该方法作为方法头的接口来实现) JComponent
JComponent
MyInterface
and are extending a JComponent (subclasses of it). MyInterface
并扩展了JComponent(它的子类)。 That's where I run in my title problem: new List<MyInterface extends JComponent);
new List<MyInterface extends JComponent);
public abstract class MyClass<X extends JComponent> extends X
, but this can't work – for obvious reasons. public abstract class MyClass<X extends JComponent> extends X
,但这是行不通的-出于明显的原因。 (eg I have to implement the abstract methods from a superclass, but if it's a Generic I cannot know by now.) I run in a problem which could easily be made if you can make this line working: 我遇到了一个问题,如果可以使此行正常工作,那么很容易做到:
new List<A extends B>();
or, introduced by @khelwood: new List(); 或由@khelwood引入:new List();
where: 哪里:
new List<MyInterface>()
new List<MyInterface>()
? extends B
? extends B
? extends B
(example: it can be a JTextField or a JTextArea or whatever they like, but it has to be a (subclass of) JComponent (JComponent = B)) ? extends B
(示例:它可以是JTextField或JTextArea或任何他们喜欢的东西, 但它必须是JComponent (的子类) (JComponent = B)) If you want to be able to create a list of things which extend JComponent
and implement your interface, and add things to such a list, you need to define a concrete type which implements both: 如果您希望能够创建扩展
JComponent
并实现您的接口的事物的列表,并将事物添加到此类列表中,则需要定义一个具体的类型,该类型同时实现这两种:
List<ThatType> list = new ArrayList<>();
list.add(new ThatType());
You can declare a type variable for this, in order to write a generic method: 您可以为此声明一个类型变量,以便编写一个通用方法:
<T extends JComponent & YourInterface> void something(T thing) {
// ...
}
<Something extends SomethingElse>
only works in the declarations of type variables. <Something extends SomethingElse>
仅适用于类型变量的声明。
Moreover, you don't create a list of Somethings that extends SomethingElse
: you create a list of Somethings
, and whether or not Something extends SomethingElse
depends upon how those types are defined. 此外,您不会创建
Somethings that extends SomethingElse
列表:您会创建Somethings
列表,并且Somethings
是否Something extends SomethingElse
取决于如何定义这些类型。
To make this more concrete, you don't make a new List<String extends Object>
: you make a List<String>
, and String
happens to extend Object
. 为了更具体一点,您不需要创建
new List<String extends Object>
:创建List<String>
,而String
恰好是Object
扩展。
You need to declare the type variables appropriately, eg: 您需要适当地声明类型变量,例如:
class Foo<B> {
<A extends B> List<A> list() {
return new List<>();
}
}
You say that: 你说:
Another idea: creating an abstract class (that fits all criteria) instead of an Interface.
另一个想法:创建一个抽象类(适合所有标准)而不是一个接口。 Problem: The concrete classes I need do not extend the same class.
问题:我需要的具体课程不会扩展同一课程。
but at the same time you say that they extend JComponent
. 但同时您说它们扩展了
JComponent
。 The only possibility for this to occur is that they all transitively extend JComponent
. 发生这种情况的唯一可能性是它们都可传递地扩展了
JComponent
。 So at some point up the inheritance hierarchy there is a direct inheritance from JComponent
. 因此,在继承层次结构的某个点上,存在来自
JComponent
的直接继承。
If this is still your code, this is the point where you could introduce another class, instead of a JComponent
that extends JComponent
and implements your interface. 如果这仍然是你的代码,这是你可以介绍的,而不是另一个类,点
JComponent
扩展JComponent
和实现你的接口。
If not then I think it could be impossible to achieve using only syntax. 如果不是这样,我认为仅使用语法是不可能实现的。
I don't think the type system allows you to do exactly what you want and get compile-time type safety. 我认为类型系统不能让您完全按照自己的意愿做,并获得编译时的类型安全。
One approximation is the following: 一种近似如下:
List<JComponent> componentList = new ArrayList<>();
List<MyInterface> myInterfaceList = (List) componentList;
If you don't mind the compile-time warning, you now have two views on the same list: one shows the content as JComponent
's and the other as MyInterface
's. 如果您不介意编译时警告,则现在在同一列表上有两个视图:一个显示内容为
JComponent
,另一个显示为MyInterface
。
You can add the objects to either view and then read them from the view that provides the right type for the context. 您可以将对象添加到任一视图中,然后从为上下文提供正确类型的视图中读取它们。
Naturally, when you add an object the compiler will not check that the inserted object subclasses both JComponent
and MyInterface
. 自然地,当您添加对象时,编译器将不会检查插入的对象是否同时
MyInterface
了JComponent
和MyInterface
子类。 That is your responsibility. 那是你的责任。
If you want more (run-time) type safety, you can go this way: 如果您想要更多(运行时)类型的安全性,可以采用以下方式:
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;
If you only insert into doublyCheckedList
, at runtime the list will check that the inserted objects subclass both JComponent
and MyInterface
. 如果仅插入
doublyCheckedList
,则在运行时列表将检查插入的对象是否同时MyInterface
了JComponent
和MyInterface
。 When reading, you can use the two views as in my previous fragment. 阅读时,您可以像我之前的片段中一样使用这两种视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.