Я хочу скопировать список в Java, и я нашел метод под названием clone
, который делает это, и он отлично работает, но я думаю, что я использую его неправильно, так как я получаю предупреждение в Eclipse .
Что я делаю, так это создаю список, добавляю к нему целое число и, наконец, использую метод копирования.
ArrayList<Integer> lista = new ArrayList<Integer>();
list.add(5);
ArrayList<Integer> listaCopiada = (ArrayList<Integer>) lista.clone();
Видимо была проблема, метод возвращает a Object
, поэтому мне пришлось его выполнить, и когда я это делаю, он у меня работает, но я получаю предупреждение.
Безопасность типов: непроверенное приведение от Object к ArrayList<Integer>
Я могу нажать на предупреждение и увидеть несколько решений, но ни одно из них меня не убеждает.
Извлечь в локальную переменную:
Это дублирует строку, а затем я получаю еще одно предупреждение того же типа.
ArrayList<Integer> clone = (ArrayList<Integer>) lista.clone();
ArrayList<Integer> clone2 = clone;
ArrayList<Integer> clone1 = clone2;
ArrayList<Integer> clone21 = clone1;
ArrayList<Integer> clone11 = clone21;
Извлечь в метод:
Это делает меня приватной функцией, внутри которой есть строка с таким же предупреждением.
ArrayList<Integer> listaCopiada = extracted(lista);
private static ArrayList<Integer> extracted(ArrayList<Integer> lista) {
return (ArrayList<Integer>) lista.clone();
}
Когда я пытаюсь исправить это предупреждение, у меня остается рекурсивная функция, которая кажется мне довольно нелогичной, поскольку она удаляет часть клонирования.
private static ArrayList<Integer> extracted1(ArrayList<Integer> lista) {
return extracted1(lista);
}
Добавьте круглые скобки вокруг приведения:
Это добавляет несколько бессмысленных скобок для меня, и следует предупреждение.
ArrayList<Integer> listaCopiada = ((ArrayList<Integer>) lista.clone());
Я получаю предложение удалить лишние скобки , это возвращается к тому, как это было раньше.
Добавьте SuppressWarnings «неотмеченные»:
Это вынуждает меня использовать комментарий к коду, говорящий мне не выдавать предупреждение. Это единственный способ, которым я больше не получаю предупреждение, но я думаю, что это выглядит некрасиво.
@SuppressWarnings("unchecked")
Есть ли способ (если можно официальный или правильный) использовать clone
без таких предупреждений?
Что касается предупреждения, единственный способ удалить его — использовать файл
@SupressWarnings
. Это происходит потому, что вы выполняете приведение к общему типу. В Java нет другого способа выполнить приведение к общему определенному объекту (в данном случае изObject
)ArrayList<Integer>
и удалить предупреждение. Нет ничего плохого в использовании@SupressWarnings
, если вы знаете, что делаете. Если бы вы удалили дженерик, вы бы получили еще одно предупреждение об использовании необработанных переменных (необработанного типа), и вам все равно пришлось бы добавить эту аннотацию.Этот метод
clone
представляет собой неудачную попытку Java реализовать шаблон прототипа . Я говорю «плохой», потому что технически он не представляет большой ценности и представляет собой всего лишь поверхностную копию. Есть только несколько случаев, когда следует вызывать метод клонирования, например, для массива.В вашем случае, если вам нужна только неглубокая копия с новым списком с теми же объектами, то есть если вы измените состояние одного из объектов в новом списке, вы также увидите изменение состояния в исходном списке ( поскольку это один и тот же объект), то достаточно следующего:
Если вы ищете глубокую копию, а это означает, что даже объекты в новом списке отличаются от оригинала и каждый из них имеет свое собственное состояние, вам нужно убедиться, что каждый элемент в вашем исходном списке либо неизменяем, либо реализует ваш собственный метод глубокого клонирования, такой как конструктор копирования, сериализация/десериализация или другой.
Я бы избегал использования
clone
. Если вы хотите скопировать список, вы можете просто сделать это следующим образом:Нет других способов удалить предупреждение, кроме как отключить этот тип сообщения.
clone
он вернет элемент типаObject
, который вы не сможете изменить.Альтернативой является прекращение использования
clone
и создание копии объекта с помощью конструктора копирования:Вы можете использовать класс
java.util.Collections
:или самый распространенный метод: