如何在 Java 中创建另一个列表,给定一个列表,但列出不同的类
我有一个列表,我需要返回相同类型的列表。
如果相关的话,在我的例子中,Y 是一个接口,接口 X 是它的超级接口。
我假设我需要使用 newInstance 来获取 List 的类型。
public List<Y> foo() {
List<X> xList = -a method that returns List<X>-;
List<Y> yList = xList.getClass().newInstance(); //Is this right?
...
return yList;
}
我可以创建一个 ArrayList,但我不知道这是否是最好的选择,因为我可以接收任何类型的列表。
I have a list, and I need to return that same type of list.
If it's relevant, in my case Y is an interface and interface X is its superinterface.
I assume that I need to use newInstance to get the type of List.
public List<Y> foo() {
List<X> xList = -a method that returns List<X>-;
List<Y> yList = xList.getClass().newInstance(); //Is this right?
...
return yList;
}
I could just make an ArrayList, but I don't know if that's the best thing to do since I could receive any type of list.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您是否将 List 的类与其泛型类型混淆了?很少需要返回
List
的特定实现(例如,如果它需要可序列化)。我建议只使用ArrayList
,并预先调整好大小。关于接口,请小心,因为如果
Y
扩展X
,则通常无法将xList
中的对象放入yList
(我假设您想要),因为列表中可能有一个X
实例不是Y
。Are you mixing up the class of the List with its generic type? There should rarely be any need to return a particular implementation of
List
(e.g., if it needs to be serializable). I recommend just using anArrayList
, sized appropriately beforehand.With regards to the interfaces, be careful because if
Y
extendsX
, you can't in general put objects fromxList
inyList
(I assume you want to), because there might be an instance ofX
in the list that isn't aY
.Java 通过擦除实现泛型,因此在运行时您将看不到
List
的.getClass()
和List的
。但是,您应该能够说:.getClass()
之间的区别;如果您不知道要使用哪个 List 实现,而这正是您想要依赖于支持
xList
的列表类型的实现,您仍然可以使用newInstance
:你只需要转换它:在运行时,你所拥有的只是一个
LinkedList
或ArrayList
或类似的东西,但只要你不要将任何非 Y 项目添加到列表中,您应该可以安全地将其作为List
返回。Java implements generics via erasure, so at runtime you will see no difference between the
.getClass()
of aList<X>
and that of aList<Y>
. However, you should be able to just say:If you don't know which List implementation to use, and that's what you want to have depend on the list type backing
xList
, you can still usenewInstance
: you just have to cast it:At runtime, all you'll have is a
LinkedList
orArrayList
or some such, but as long as you don't add any non-Y items to the list, you should be safe returning it as aList<Y>
.由于您不知道 List 的类型,因此您也不知道它是否有公共无参数构造函数,因此您无法确定 newInstance() 不会抛出异常。
如果您不需要列表的副本,并且您知道该列表实际上包含 Y 实例,您可以这样做
Since you don't know the type of the List, you don't know if it has a public no-arg constructor either, so you can't be sure that newInstance() won't throw an exception.
If you don't want a copy of the list, and you know that the list actually contains Y instances, you could just do
仅当无参数构造函数可用时才有效。如果它不可访问,您可能需要使用反射覆盖访问可见性:
如果该类没有可用的无参数构造函数,那么您可能不走运!
建议实现类时提供以下形式的构造函数:
如果存在这样的构造函数,您可以尝试使用反射调用该构造函数并向其传递一个空列表。在一般情况下,不可能确定调用哪个构造函数:(
will work only if the no-args constructor is available. If it is not accessible, you may need to override the access visibility using reflection:
If there is no no-args constructor available for the Class, then you are probably out of luck!
It is advised for implementing classes to provide a constructor of the form:
If such a constructor exists, you may try invoking that constructor using reflection and passing it an empty List. It will not be possible, in the general case, to determine which constructor to call :(