2010-02-20 5 views
3

Что такое быстрый и простой способ заполнения массива Java клонами одного объекта?Заполнение массива клонами одного объекта

например. после того, как:

Rectangle[] rectangles = new Rectangle[N]; 
fillWithClones(rectangles, new Rectangle(1, 2, 3, 4)); 

rectangles массив будет содержать N различных Rectangle экземпляров, инициализированы с теми же координатами.

Я знаю об ошибках Object.clone() на Java, но в этом случае я знаю, что объекты, подлежащие копированию, имеют не-бросающие, общедоступные методы clone(), но могут иметь или не иметь открытый конструктор копирования.

Я предполагаю, что есть где-то библиотечный метод, но я не думаю, что это в JDK, Commons-collection или Guava.

ответ

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); 
} 
+0

Вторая сигнатура метода должна быть упрощена до 'public static void fillWithClones (массив Object [], шаблон объекта)' – user102008

0

Для прямоугольников:

public void fillWithClones(Rectangle[] arr, Rectangle src) { 
    for(int xa=0,len=arr.length; xa<len; xa++) { arr[xa]=(Rectangle)src.clone(); } 
    } 
+0

Для неизвестных типов 'Object.clone' защищен. Вы можете получить доступ к этому методу только через отражение (и только если целевой тип определяет публичное переопределение, конечно). –

+0

@ Крис: Дерьмо, что такое клонирование. Я удалил неправильный нетипизированный метод. –

0

@ Крис Джеттер-Янг дает вам рецепт для выполнения того, что вы хотите сделать.

Но я бы предположил, что в приложении есть что-то довольно неправильное, что делает такие вещи.

  • Почему ваше приложение потребность сделать глубокие копии массивов случайных вещей? Если вы не знаете типы вещей, откуда вы знаете, что копирование необходимо?

  • Какое приложение должно выполняться, когда массив содержит не клонируемый объект? Вы делаете исключение? Вы помещаете в массив массив null, требующий более поздней проверки нуля?

Лучше всего иметь все объекты, которые вы хотите клонировать, реализовать интерфейс с помощью метода (общедоступного) метода клонирования. Таким образом, у вас может быть статически типизированное решение (без исключений динамического типа!), И вы можете избежать накладных расходов при вызове clone рефлексивно.

+0

Типы не являются «случайными».Тип известен в каждом случае, но я бы предпочел, чтобы общий метод не уменьшал программу. Некоторые из классов принадлежат JDK, поэтому я не могу определить для них новый интерфейс. Если этот метод встречается с не клонируемым объектом, он должен вызывать 'CloneNotSupportedException'. – finnw

+0

@finnw - как насчет первой пули? Почему ваше приложение должно сначала клонировать объекты? –

0

Если конструктор копирования мощь существует (и вы хотите использовать его, если он делает), вы могли бы сделать что-то вроде этого:

(Edit: Обновлен код, чтобы использовать массив вместо списка):

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... 
    } 
} 

Некоторые обработки исключений может быть убрано, конечно.

+0

Конструктор 'T (T)' не обязательно является конструктором копирования (например, 'JFrame',' JScrollPane', 'ClassLoader',' Properties', 'Throwable'.) – finnw

+0

@finnw: Да, хороший пикап. Думаю, в конце дня вам нужно знать _something_ о объектах, которые вы дублируете, чтобы выбрать подходящее решение. – Ash

+0

Дженерики здесь не действуют. Просто сделайте 'private static void fillWithClones (Object [] array, Object object)' и измените 'T' на'? ' – user102008

Смежные вопросы