2012-01-18 2 views
1

я получил непроверенную ошибку выражения при компиляции и найти строку, вызвавшую бытьJava небезопасные или непроверенные выражений: Клонирование ArrayList

ArrayList<Integer> items = (ArrayList<Integer>) this.items.clone(); 

Я пытаюсь выполнить глубокую копию моего объекта, поэтому я Клонирование свойства объекта и списка массивов указанным выше способом. Как я могу исправить это предупреждение?

  • я мог бы использовать @SuppressWarnings("unchecked"), но это просто скрывает проблему (Тхо я не ожидал никто)
  • Если я клонировать вручную цикл через все элементы к нему будет медленнее, я думаю

Будет правильный способ сделать это?

ответ

4

Если ваши элементы являются целыми, выполнение «глубокой копии» действительно не является проблемой, так как нет причин, по которым вам нужно будет скопировать объект Integer. Просто используйте new ArrayList<Integer>(this.items).

Но для справки ни клоун(), ни конструктор копии ArrayList не сделают глубокую копию. Это связано только с тем, что ваши типы элементов не нуждаются в глубоком копировании, что удовлетворяет ваши потребности.

1

Аналогичное поведение можно получить с помощью new ArrayList<Integer>(this.items). В любом случае, это мелкой копия.

API

+0

Конечно, нет необходимости делать глубокую копию объектов Integer. –

0

Благодаря обратной совместимости требуется, когда они введены дженериков в API Java, нет никакого способа вокруг использования литья и @SuppressWarnings("unchecked") в некоторых ситуациях.

Кроме того, см. here по причине, почему использование clone() следует использовать с осторожностью: оно делает мелкую копию, что отлично подходит для первобытных людей, но опасно для объектов.

+0

Вы можете поместить примитивы в 'ArrayLists'? Я думал, что вы можете только поместить объекты и, в лучшем случае, обертки для примитивов. – blahman

+0

@blahman Дело в том, что при клонировании примитивные поля хороши, но поля объектов (например, ArrayList items') являются источниками проблем. –

+0

Ох ... упс. Полностью пропустил это. Извините, Yuushi. Мой плохой ^^ 'Также, спасибо @TedHopp =) – blahman

0

Вы сказали, что пытаетесь сделать глубокую копию, но, как обсуждалось, here, я сомневаюсь, что вы сможете это сделать, используя clone(). Так, как и другие плакаты, это несколько более опасный способ использовать clone(), и вы не сможете получить глубокую копию, которую вы искали.

1

Целые числа неизменны, поэтому не имеет значения, сделаете ли вы глубокую копию или нет.

использовать класс Коллекции утилиты в java.util:

import java.util.Collections; 
... 
ArrayList<Integer> items = new ArrayList<Integer>(this.items.size()); 
Collections.copy(items, this.items); 
+0

'Arrays.copyOf' не возвращает' ArrayList'. –

+0

К сожалению, это значит Collections.copy, а не Array.copyOf. – marathon

0

Как уже отмечалось, клонирование ArrayList не клонировать его элементы. Если вы хотите сделать глубокую копию содержимого, есть аккуратный трюк: сериализовать и десериализовать массив. (Это работает, потому что ArrayList и Integer оба реализуют Serializable.) Однако это не избавляет от необходимости подавлять непроверенные предупреждения о конверсиях.

// Write the object out to a byte array 
ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
ObjectOutputStream out = new ObjectOutputStream(bos); 
out.writeObject(this.items); 
byte[] bytes = bos.toByteArray(); 

// Retrieve an input stream from the byte array and read 
// a copy of the object back in. 
ObjectInputStream in = new ObjectInputStream(
    new ByteArrayInputStream(bytes)); 
ArrayList<Integer> items = (ArrayList<Integer>) in.readObject(); 

Если весь ваш объект может быть объявлен Сериализуемым, вы могли бы использовать это вместо операции клонирования, чтобы сделать вашу глубокую копию. Кроме того, см. this article, чтобы избежать затрат на копирование байтов из ByteArrayOutputStream.

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