我有一个列表,我需要返回相同类型的列表。
如果它是相关的,在我的情况下,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,但我不知道这是否是最好的事情,因为我可以收到任何类型的列表。
答案 0 :(得分:1)
您是否将List的类与其泛型类型混合在一起?应该很少需要返回List
的特定实现(例如,如果它需要可序列化)。我建议您事先使用适当大小的ArrayList
。
关于接口,请注意,因为如果Y
扩展X
,您通常无法将xList
中的对象放入yList
(我假设您需要) to),因为列表中可能有X
的实例不是Y
。
答案 1 :(得分:0)
Java通过擦除实现泛型,因此在运行时,您会发现.getClass()
的{{1}}与List<X>
的{{1}}之间没有区别。但是,您应该只能说:
List<Y>
如果您不知道要使用哪个List实现,并且您希望依赖于支持List<Y> yList = new ArrayList<Y>(); // Or LinkedList, or whatever implementation you want.
的列表类型,您仍然可以使用xList
:您只需要使用它:
newInstance
在运行时,你所拥有的只是List<Y> yList = (List<Y>)xList.getClass().newInstance();
或LinkedList
或其他一些,但只要你不在列表中添加任何非Y项,你就应该是安全的将其作为ArrayList
返回。
答案 2 :(得分:0)
由于你不知道List的类型,你不知道它是否也有一个公共的无参数构造函数,所以你不能确定newInstance()不会抛出异常。 / p>
如果您不想要列表的副本,并且您知道该列表实际上包含Y个实例,那么您可以这样做
List<Y> yList = (List) xList;
答案 3 :(得分:0)
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();
如果Class没有no-args构造函数,那么你可能运气不好! 建议实现类以提供以下形式的构造函数:
public MyListClass(Collection<T> items)
如果存在这样的构造函数,您可以尝试使用反射调用该构造函数并将其传递给空List。在一般情况下,无法确定要调用的构造函数:(