Лучшая практика для возврата ссылок на объект

Рассмотрите этот фрагмент кода:

class MyClass{
    private List myList;
    //...
    public List getList(){
        return myList;
    }
}

Поскольку Java передает ссылки на объект значением, мое понимание то, что любой объектный вызов getList() получит ссылку на myList, разрешение этого изменить myList несмотря на него быть private. Это корректно?

И, если это корректно, должен я использовать

return new LinkedList(myList);

создать копию и пасовать назад ссылку на копию, а не оригинал, для предотвращения несанкционированного доступа к списку, на который ссылаютсяmyList?

8
задан chrisbunney 11 July 2010 в 21:30
поделиться

5 ответов

Я так и делаю. Еще лучше, иногда я возвращаю неизменяемую копию, используя API Collections.

Если вы этого не делаете, ваша ссылка не является приватной. Любой, у кого есть ссылка, может изменить ваше приватное состояние. То же самое справедливо для любой изменяемой ссылки (например, Date).

9
ответ дан 5 December 2019 в 12:54
поделиться

Это зависит от того, что вы хотите.

Хотите ли вы раскрыть список и сделать так, чтобы люди могли его редактировать?

Или вы хотите позволить людям смотреть на него, но не изменять?

В этом случае нет правильного или неправильного пути. Это просто зависит от ваших потребностей в дизайне.

2
ответ дан 5 December 2019 в 12:54
поделиться

В некоторых случаях может потребоваться вернуть "необработанный" список вызывающей стороне. Но в целом я считаю, что это плохая практика, поскольку она нарушает инкапсуляцию и, следовательно, против OO. Если вы должны вернуть «необработанный» список, а не копию, он должен быть явно понятен пользователям MyClass.

1
ответ дан 5 December 2019 в 12:54
поделиться

Да, и у него есть название... "Защитное копирование". Копирование на принимающей стороне также рекомендуется. Как отметил Том, поведение программы гораздо легче предсказать, если коллекция неизменяема. Поэтому, если у вас нет очень веской причины, вы должны использовать неизменяемую коллекцию.

Когда Google Guava станет частью стандартной библиотеки Java (я считаю, что так и должно быть), эта идиома, вероятно, станет предпочтительной:

return ImmutableList.copyOf(someList);

и

void (List someList){
    someList = ImmutableList.copyOf(someList);

Это имеет дополнительный бонус производительности, потому что метод copyOf() проверяет, является ли коллекция уже экземпляром неизменяемой коллекции (instanceof ImmutableList), и если да, то пропускает копирование.

0
ответ дан 5 December 2019 в 12:54
поделиться

Я думаю, что шаблон создания частных полей и предоставления средств доступа просто предназначен для инкапсуляции данных. Если вы хотите, чтобы что-то было действительно приватным, не давайте ему методы доступа! Затем вы можете написать другие методы, которые возвращают неизменяемые версии ваших личных данных или их копии.

1
ответ дан 5 December 2019 в 12:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: