繁体   English   中英

如何在Java中创建另一个List(给定一个List,但列出了另一个类)

[英]How to make another List in Java, given a List, but with a different class listed

我有一个列表,我需要返回相同类型的列表。

如果相关,在我的情况下,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,但是我不知道这是否是最好的方法,因为我可以接收任何类型的列表。

您是否要混合使用List的类和其泛型? 很少需要返回List的特定实现(例如,如果需要序列化)。 我建议只使用预先设置大小的ArrayList

关于接口,要小心,因为如果Y扩展X ,则通常不能将xList中的对象放入yList (我想您想这样做),因为列表中可能存在X的实例,而该实例不是Y

Java通过擦除实现泛型,因此在运行时,您不会看到List<X>.getClass()List<Y>.getClass()之间的.getClass() 但是,您应该只能说:

List<Y> yList = new ArrayList<Y>(); // Or LinkedList, or whatever implementation you want.

如果您不知道要使用哪个List实现,而这取决于xList的列表类型,您仍然可以使用newInstance :您只需要newInstance转换它:

List<Y> yList = (List<Y>)xList.getClass().newInstance();

在运行时,您所拥有的只是一个LinkedListArrayList或类似的东西,但是只要您不向列表中添加任何非Y项,就应该安全地将其作为List<Y>

由于您不知道List的类型,因此您也不知道它是否具有公共的无参数构造函数,因此无法确定newInstance()不会引发异常。

如果您不想要该列表的副本,并且知道该列表实际上包含Y个实例,则可以这样做

List<Y> yList = (List) xList;
List<Y> yList = (List<Y>) xList.getClass().newInstance();

仅在no-args构造函数可用时才有效。 如果无法访问,则可能需要使用反射覆盖访问可见性:

final Constructor cons = xList.getClass().getDeclaredConstructor();
cons.setAccessible(true);
List<Y> yList = (List<Y>) cons.newInstance();

如果该类没有可用的无参数构造函数,那么您可能不走运! 建议实现类提供以下形式的构造函数:

public MyListClass(Collection<T> items)

如果存在这样的构造函数,则可以尝试使用反射调用该构造函数并将其传递给空的List。 通常情况下,无法确定要调用哪个构造函数:(

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM