使用单个对象的克隆填充Java数组的快速简便方法是什么?
e.g。后:
Rectangle[] rectangles = new Rectangle[N];
fillWithClones(rectangles, new Rectangle(1, 2, 3, 4));
rectangles
数组将包含N个不同的Rectangle
个实例,并使用相同的坐标进行初始化。
我知道Java中Object.clone()
的缺陷,但在这种情况下,我知道要复制的对象具有非抛出的公共clone()
方法,但可能有也可能没有公开复制构造函数。
我猜这里有一个库方法可以做到这一点,但我不认为它存在于JDK,Commons-collections或Guava中。
答案 0 :(得分:2)
如果您没有在编译时使用的特定类型,则必须通过反射调用clone
方法。
private static <T> T cloneByReflection(T object) {
try {
return (T) object.getClass().getMethod("clone").invoke(object);
} catch (Exception e) {
return null; // or whatever you want to do
}
}
public static <T> void fillWithClones(T[] array, T template) {
for (int i = 0; i < array.length; ++i)
array[i] = cloneByReflection(template);
}
答案 1 :(得分:0)
对于矩形:
public void fillWithClones(Rectangle[] arr, Rectangle src) {
for(int xa=0,len=arr.length; xa<len; xa++) { arr[xa]=(Rectangle)src.clone(); }
}
答案 2 :(得分:0)
@Chris Jester-Young给你一个做你想做的事情的方法。
但我建议应用程序执行此类操作时会出现一些错误。
为什么您的应用需要来制作随机数组的深层副本?如果你不知道事物的类型,你怎么知道复制是必要的?
当数组包含不可克隆的对象时,您的应用程序应该做什么?你抛出一个例外吗?你在数组中加了一个null
,需要稍后进行空检查吗?
更好的设计是让您可能要克隆的所有对象都实现具有(公共)克隆方法方法的接口。这样你就可以得到一个静态类型的解决方案(没有动态类型异常!),你可以避免反复调用clone
的开销。
答案 3 :(得分:0)
如果复制构造函数可能存在(如果有的话你想使用它),你可以这样做:
(编辑:更新了使用数组代替List的代码):
private static <T> void fillWithClones( T[] array, T object )
{
try
{
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>)object.getClass();
Constructor<T> c = clazz.getConstructor( object.getClass() );
try
{
for ( int i = 0; i < array.length; i++ )
{
array[i] = (T)c.newInstance( object );
}
}
catch ( Exception e )
{
// Handle exception or rethrow...
}
}
catch ( NoSuchMethodException e )
{
// No copy constructor, try clone option...
}
}
当然,有些异常处理可以整理。