Неизменяемый список в 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 интерфейс и выбрасывать исключения для методов, которые изменяют содержимое.

Collections.unmodifiableList

Возвращает неизменяемое представление указанного списка. Этот метод позволяет модулям предоставлять пользователям доступ "только для чтения" к внутренним спискам. Операции запроса в возвращаемом списке "считываются" в указанный список и пытаются изменить возвращенный список, будь то прямой или через его итератор, приводят к исключению 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();
 }
Другие вопросы по тегам