Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中创建另一个列表,给定一个列表,但列出的类不同_Java_List_Generics_Instance - Fatal编程技术网

如何在Java中创建另一个列表,给定一个列表,但列出的类不同

如何在Java中创建另一个列表,给定一个列表,但列出的类不同,java,list,generics,instance,Java,List,Generics,Instance,我有一个列表,我需要返回相同类型的列表 如果相关的话,在我的例子中,Y是一个接口,X是它的超级接口 我假设我需要使用newInstance来获取列表的类型 public List<Y> foo() { List<X> xList = -a method that returns List<X>-; List<Y> yList = xList.getClass().newInstance(); //Is this right?

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

如果相关的话,在我的例子中,Y是一个接口,X是它的超级接口

我假设我需要使用newInstance来获取列表的类型

public List<Y> foo() {
    List<X> xList = -a method that returns List<X>-;
    List<Y> yList = xList.getClass().newInstance(); //Is this right?

    ...

    return yList;
}
公共列表foo(){
List xList=-返回List-的方法;
List yList=xList.getClass().newInstance();//是否正确?
...
返回yList;
}

我可以创建一个ArrayList,但我不知道这是否是最好的做法,因为我可以收到任何类型的列表。

Java通过擦除实现泛型,因此在运行时,您将看到
列表的
.getClass()
列表的
之间没有区别。然而,你应该能够说:

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

在运行时,您所拥有的只是一个
LinkedList
ArrayList
或诸如此类的列表,但是只要您不向列表中添加任何非Y项,您应该可以安全地将其作为
列表返回,因为您不知道列表的类型,您也不知道它是否有一个公共的无参数构造函数,因此,您无法确保newInstance()不会引发异常

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

List<Y> yList = (List) xList;
List-yList=(List)xList;
List yList=(List)xList.getClass().newInstance();
将仅在无参数构造函数可用时工作。如果不可访问,则可能需要使用反射覆盖访问可见性:

final Constructor cons = xList.getClass().getDeclaredConstructor();
cons.setAccessible(true);
List<Y> yList = (List<Y>) cons.newInstance();
final构造函数cons=xList.getClass().getDeclaredConstructor();
cons.setAccessible(true);
List yList=(List)cons.newInstance();
如果该类没有可用的args构造函数,那么您可能运气不好! 建议实现类时提供以下形式的构造函数:

public MyListClass(Collection<T> items)
公共MyListClass(集合项)

如果存在这样的构造函数,您可以尝试使用反射调用该构造函数,并向其传递一个空列表。在一般情况下,无法确定要调用哪个构造函数:(

是否将列表的类与其泛型类型混淆了?应该很少需要返回
列表的特定实现(例如,如果需要序列化)。我建议只使用
阵列列表
,事先调整大小


关于接口,要小心,因为如果
Y
扩展
X
,通常不能将
xList
中的对象放入
yList
(我假设您想要),因为列表中可能有一个非
Y

X
实例,我想他的目的是创建一个与现有列表类型相同的新列表,但在编译时不知道该列表的类型。@MattiVirkkunen:谢谢您的输入。我相应地更新了我的答案。是的,这就是我要问的。@user1195265:我很好奇知道为什么,确切地说,你需要这种行为。你确定保留原来的列表实现很重要吗?你真的需要一个新的列表吗?@StriplingWarrior我可能错了,实际上需要这个解决方案,但我想确定。而且,不知道答案让我发疯了!@@如果你只分享一下你不需要它吗?第一眼就看出你可能在试图用最复杂的方式做一些非常简单的事情。为什么你不能把它作为
列表
对象本身呢?在我的特殊情况下,我认为这个解决方案是最合适的。@JBNizet:很抱歉,我误解了答案。我想它说的是“如果你只想要一份列表的副本”,现在StackOverflow不允许我删除我的下一票,除非你编辑答案。好的。不需要删除你的下一票。我只是想知道为什么我有下一票。现在一切都清楚了。谢谢你的警告,但我还是转换了它们,所以我知道它们都是Y。
final Constructor cons = xList.getClass().getDeclaredConstructor();
cons.setAccessible(true);
List<Y> yList = (List<Y>) cons.newInstance();
public MyListClass(Collection<T> items)