[英]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();
在运行时,您所拥有的只是一个LinkedList
或ArrayList
或类似的东西,但是只要您不向列表中添加任何非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.