Неизменяемый список в Java
Я пытаюсь установить List
неизменяемый.
В моем коде у меня есть метод, который возвращает список.
Этот список не должен быть изменен, но я не хочу перехватывать исключение, возвращаемое unmodifiableList.
private List<T> listeReferenceSelectAll = null;
List<T> oListeRet = new ArrayList<T>();
oListeRet = listeReferenceSelectAll;
return new ArrayList<T>(oListeRet);
Это существующий код, и мне нужно преобразовать его, чтобы он возвращал неизменяемый список, но если был вызван метод add, исключение перехватывать не нужно.
Сначала я создал класс, который реализует List для переопределения метода "add" для регистрации исключения, а не для его перехвата.
Но я не знаю, как правильно создать его экземпляр...
7 ответов
Если вы абсолютно обязаны это сделать, попробуйте следовать контракту, указанному java.util.List в списке, который вы создаете.
Ваш код будет выглядеть примерно так
public class UnmodifiableArrayList<E> extends ArrayList<E> {
public UnmodifiableArrayList(Collection<? extends E> c) {
super(c);
}
public boolean add(int index) {
return false;//Returning false as the element cannot be added
}
public boolean addAll(Collection<? extends E> c) {
return false;//Returning false as the element cannot be added
}
public E remove(int index) {
return null;//Returning null as the element cannot be removed
}
}
Добавьте любые другие методы, которые вам нужны, в тех же строках. Просто убедитесь, что все конструкторы и методы, которые могли бы использоваться для изменения в вашем коде, были переопределены, чтобы гарантировать неизменность списка.
Использование API коллекций является более чистым и лучшим способом сделать это, поэтому используйте этот способ только в том случае, если использование Collections.UnmodifiableList не удовлетворяет вашу потребность.
И имейте в виду, что это будет кошмар во время отладки, поэтому регистрируйте как можно больше.
Тебе нужно java.util.Collections
:
return Collections.unmodifiableList(oListeRet);
Если вам нужно написать свой собственный, пусть этот класс реализует List
интерфейс и выбрасывать исключения для методов, которые изменяют содержимое.
Возвращает неизменяемое представление указанного списка. Этот метод позволяет модулям предоставлять пользователям доступ "только для чтения" к внутренним спискам. Операции запроса в возвращаемом списке "считываются" в указанный список и пытаются изменить возвращенный список, будь то прямой или через его итератор, приводят к исключению UnsupportedOperationException. Возвращенный список будет сериализуемым, если указанный список сериализуем. Точно так же возвращенный список будет реализовывать RandomAccess, если указанный список делает.
Java-9
предоставляет новые методы для создания неизменяемых / неизменяемых List
:
jshell> List<Integer> list = List.of(1,2,3);
list ==> [1, 2, 3]
jshell> list.add(10);
| java.lang.UnsupportedOperationException thrown:
| at ImmutableCollections.uoe (ImmutableCollections.java:70)
| at ImmutableCollections$AbstractImmutableList.add (ImmutableCollections.java:76)
| at (#6:1)
List.of создает неизменный список, содержащий произвольное количество элементов.
Хотя принятый ответ направлен на просьбу опустить / проглотить UnsupportedOperationException
Должно быть объяснение, почему это нежелательная практика.
1) Общее намерение проглотить исключение является противоречием принципа "быстрого отказа". Вместо того, чтобы рано обнаруживать и ловить дефекты, им просто позволяют идти "под ковер", превращаясь в бомбы замедленного действия.
2) Не бросать UnsupportedOperationException
является прямым нарушением List
Контракт, в котором говорится:
Throws:
UnsupportedOperationException - if the add method is not supported by this list.
Таким образом, правильный ответ на то, что написано в заголовке вопроса: "Список не изменяемых в Java" должен быть:
return Collections.unmodifiableList(oListeRet);
1) Эти строки не имеют смысла
List<T> oListeRet = new ArrayList<T>();
oListeRet = listeReferenceSelectAll;
2) Используйте Collections.unmodifiableList.
return Collections.unmodifiableList(oListeRet);
Вам не нужно перехватывать исключение, которое оно может выдать, все они UnsupportedOperationException - RuntimeExceptions
Комментарии о неизменяемом списке верны. Сделайте метод доступа метода, который вызывает Collections.unmodifiableList. Тем не менее, вы можете просто использовать массив, как это, и использовать список внутри.
public MyObject[] getObjects() {
return (MyObject[]) mList.toArray();
}