3 回答
TA贡献1884条经验 获得超4个赞
正如你自己所说:
我想到的第一件事是:ids.getClass().newInstance(),但它需要被InstantiationException和TrastralyAccessException的try/catch块包围,特别是因为我不确定ids的实际实现是否有一个空的构造函数。有没有更直接的东西?
当您甚至不知道构造函数的样子时,如何构造基础类的实例?通过反射,你知道一个(可能有多个)构造函数是什么样子的,你仍然需要担心这样的事情:
私有 vs 内部/包私有 vs 公共 - 您如何处理每个案例?一些实现,例如在番石榴库中找到的那些,使用构建器模式来构造集合,从而使构造函数私有。
List构造函数参数的数量 - 如果有多个,如何构造其余参数?
构造函数引发的异常 - 如何捕获所有异常?不要说“抓住”,因为你可能会错过。
ExceptionThrowable多个构造函数 - 如何决定调用哪个构造函数?
还有更多的角落案例需要处理...
您应该采用 KISS (Keep It Simple Soldier) 原则以及 SoC (Separation of Concerns) 原则。保持简单,你会得到回报。让使用 Pojo 的人决定如何检索列表。只要您(通过文档)明确说明该方法的作用,就由用户决定如何使用该方法做出理性的决定。
如果他们做这样的事情:
LinkedList<Integer> myIds = ...; myPojo.setIds(myIds);
然后让他们决定如何检索 ;他们可以强制转换返回的类型或制作副本。ids
如果您在文档中明确指出该列表已复制,则使用此 POJO 的人在检索它时应该知道要将其作为副本进行复制,否则他们应该安全地将列表转换为 .LinkedListLinkedList
我仍然认为,即使是上述内容也不够简单。最简单的方法(这是被广泛接受的)是使用最通用的类型来完成所需的工作。如果需要映射类型,请使用 、而不是 元组 或 元组;如果您需要一个唯一的集合,请使用 ,如果您需要一个通用的集合,请使用 等。MapHashMapList/SetSetList
TA贡献1780条经验 获得超1个赞
有没有更直接的东西?
有两种可能的方法可以做到这一点:
您建议的方法:使用反射调用 no-args 构造函数,创建一个新的空列表,然后用于将元素复制到新列表。
List::addAll使用该方法创建副本。
Object::clone
任何一种方法(如果有效!)都将创建与原始类型相同的列表对象。但是,这两种方法都不能保证适用于所有可能的类。List
如果列表实现类没有可用/可访问的无参数构造函数,则反射方法将失败。
如果列表实现类未正确重写,则此方法将失败。
cloneObject::clone
请注意,这些不是假设的问题。列表实现类可能被特意设计为防止程序克隆列表。例如,列表和(比如)数据库查询结果集之间可能存在某种关系,因此克隆毫无意义。
但另一方面,如果库设计人员没有提供无参数构造函数或重写,他们这样做可能是有充分理由的。clone
最后,您应该尝试这样做是值得怀疑的。类属性没有明显的理由使用与原始参数相同的类。这实际上使行为类依赖于所提供列表的行为。我认为这是一件坏事,因为你正在削弱你的类的抽象边界。MyPojoidsListMyPojoMyPojo
TA贡献1772条经验 获得超5个赞
例如,您可以使用Arrays.asList
public void setIds(List<Integer> ids) {
this.ids = Arrays.asList(ids.toArray(new Integer[ids.size()]));
}
这应该适用于Java 1.6
添加回答
举报
