Вопрос

Я действительно восхищаюсь челюсти Java, и я не хочу сдаваться, используя его для следующей проблемы:

У меня есть класс, который может быть унаследован, и внутри этого является private ArrayList arr; Таким образом, функция сеттера в порядке, но функция getter return arr; Возвращает ссылку на эту переменную, которую кто-то способен редактировать этот целый массив, который я не хочу, и в частном случае не имеет никакого смысла!

В C ++ я бы просто return const arr; И это вернуло бы постоянную ссылку на переменную.

Мне так нужна вариабельная не к клонированию или вручную скопирована, потому что есть так много расчетов, которые требуют (читают только переменную), почему нет постоянного возвращения в Java ???? Есть ли способ избежать копирования?

PS. (final ArrayList<Integer> arr;) Разве опция не причина того, что массив всегда меняет размер или значения элементов.

Если бы я не мог найти починку к тому, что я угрожаю вернуться к C ++ или сделать все публику, и вы никогда не должны получать свое программное обеспечение: D


Редактировать: Еще один важный вопрос: я прошу о чем-то, что не хорошо (программное обеспечение Wise), я имею в виду, если бы создатели Java думали, что не имея константы (возвращение чтения только ссылки), то я должен просить то, что можно обрабатывать в других способ. Или мой дизайн программы не прав, я так запутался.

Это было полезно?

Решение

Оберните возвращаемое значение с java.util.coldions.unmodifialeList. Отказ Он не делает копию данных, а заворачивает оригинальный список и делегирует операции только для чтения в базовый список. Операции, которые будут изменять список, отклоняются во время выполнения через UnsupportedOperationException.

Твой

return arrayList;

становится

return Collections.unmodifiableList(arrayList);

К сожалению, ограничения только для чтения не будут применяться компилятором. Они, однако, будут применяться во время выполнения.

Вы также имеете доступ к вам: немодифицировать, UnmoDifiablemap, UnmoDifiallecollection, немодифицировать, а также немодифицировать. Отказ И если этого недостаточно, вы все равно можете взять вдохновение от этого общего дизайна подхода и создать собственные пользовательские классы обертки только для чтения.

Другие советы

:) У вас есть несколько вариантов:

  • Не выставляйте Getter, предоставьте только методы, которые могут позвонить, например,

    public void addToList(Object arg) { this.arr.add(arg);}

  • Возврат неизменного объекта:

    public List getArr() { return Collections.unmodifiableList(this.arr); }

Вы также можете использовать Google Guavaнеизменный коллекции. Отказ В этом случае вы будете хранить Иммутаблел в вашей области.

Конечно, если ваш класс должен изменять этот список внутри, используя Immutablist мощь Оказывается плохой идеей, поскольку вам нужно будет создать новый экземпляр иммутаблела и переназначить его в поле каждый раз ...

Но это идеально, если вы знаете, список не изменится после строительства объекта.

Неизменный пример (список не изменится после конструкции объекта)

@Immutable
public final class Foo {

    @Nonnull
    private final ImmutableList<String> list;

    public Foo(@Nonnull List<String> list) {
        // you could also compute the appropriate list here
        // before assigning it to the field
        this.list = ImmutableList.copyOf(list);
    }


    public ImmutableList<String> getList() {
        return list;
    }
}

Союзный пример (список может быть изменен только с помощью сеттера)

public class Foo {

    @Nonnull
    private ImmutableList<String> list = ImmutableList.of();

    public ImmutableList<String> getList() {
        return list;
    }

    public void setList(@Nonnull List<String> list) {
        this.list = ImmutableList.copyOf(list);
    }
}

Замечания

  • Я знаю, что часто рекомендуется сделать методы возврата максимально возможным типом (List В этом случае), но я предпочитаю объявить тип возвращения своего Getter в качестве ImmutableList, Поскольку он действует как документация (не нужно документировать неподумность возвращенного списка в JavadoC) и как договор API. Это как сказать: «Я гарантия Этот список, чтобы быть неизменным, вам не нужно беспокоиться или защищать его ». И это очень лаконично.
  • ImmutableList.copyOf() отлично, так как он автоматически отклоняет нулевые списки (путем бросания NullPointerException). Это также отвергает нулевые элементы. И это не будет скопировать список исходных сигналов, если он уже неизвестный иммутаблельник, который позволяет избежать бесполезной объектной инстанции.
  • Во втором примере я инициализирую поле для пустого иммутаблела, используя ImmutableList.of(), Поскольку это хорошая практика для возвращения пустых коллекций вместо нулевых значений (NULL Object Pattern). Вы можете подумать, что это создает ненужную экскурировать объект, но ImmutableList.of() на самом деле возвращает синглтон.

Существует альтернатива методу NumboDifialleList. Вы можете просто вернуть копию этого частного массива. Например,

    return your_private_array.clone();

Ну, для этого может быть штраф производительности. Но у вас есть интерфейс без изменений (вы все еще возвращаете массив).

UnmoDifiableList Определенно ответ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top