我有一个克隆不同对象的旧代码。 list
声明为 java.util.List
CloneUtils.cloneList(list);
cloneList
内的内容如下:
public static List cloneList(final List list) throws CloneNotSupportedException {
List list2;
try {
list2 = list.getClass().newInstance();
} catch (Exception e) {
Log.debug(e);
list2 = new ArrayList();
}
对cloneList
的调用引发异常:
jvm 1 | DEBUG[2012-10-09 16:57:58,611]: java.util.Arrays$ArrayList
jvm 1 | java.lang.InstantiationException: java.util.Arrays$ArrayList
jvm 1 | at java.lang.Class.newInstance0(Class.java:340)
jvm 1 | at java.lang.Class.newInstance(Class.java:308)
jvm 1 | at com.acme.common.util.CloneUtils.cloneList(CloneUtils.java:
88)
jvm 1 | at com.acme.common.data.PropertyDescriptor.clone(PropertyDesc
riptor.java:165)
jvm 1 | at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
jvm 1 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMet
hodAccessorImpl.java:25)
jvm 1 | at java.lang.reflect.Method.invoke(Method.java:597)
是否可以创建一个与使用反射传递给cloneList
方法的类型相同的新对象?
EDIT1
传递给list
方法的cloneList
参数来自:
String[] fields = field.split(",");
list = Arrays.asList(fields);
答案 0 :(得分:1)
操作Arrays.asList(String[]);
返回 Arrays.ArrayList ,而不是java.util.ArrayList。
参见asList实现,
public static <T> List<T> asList(final T... a)
{
return new Arrays.ArrayList(a);
}
Arrays.ArrayList是ArraysClass
中的静态内部类 private static final class ArrayList<E> extends AbstractList<E>
implements Serializable, RandomAccess
{
..
..
但我不明白的是这种操作的意图(以不同的方式克隆列表)。
答案 1 :(得分:0)
来自Arrays$ArrayList
的{{3}} - 似乎该类没有空构造函数,因此您无法使用空newInstance()
请注意,您获得例外的课程为java.util.Arrays$ArrayList
而非source。
反射的问题是 - 你不知道如何实例化所有对象 - 所以构建“所有案例实例化”几乎是不可能的,除非你对哪些构造函数有一些指导规则必须实施。
在大多数情况下可能的替代方案是使用java.util.ArrayList
而不是反射来创建新对象,但我怀疑你可以在这里使用它而不需要进行更多的修改。
答案 2 :(得分:0)
只要原始对象的类具有no-args构造函数,那么这将起作用。 (ArrayList DOES有一个no-args构造函数,并且可以正常工作)
static Object makeSameType(Object original) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> originalClass = original.getClass();
Constructor<?> con = originalClass.getConstructor();
return con.newInstance();
}