Лучшие практики для возврата ссылок на объекты - PullRequest
8 голосов
/ 12 июля 2010

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

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

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

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

return new LinkedList(myList);

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

Ответы [ 5 ]

9 голосов
/ 12 июля 2010

Я делаю это.А еще лучше, иногда я возвращаю немодифицируемую копию с помощью API коллекций.

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

2 голосов
/ 12 июля 2010

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

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

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

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

1 голос
/ 12 июля 2010

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

1 голос
/ 12 июля 2010

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

0 голосов
/ 12 июля 2010

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

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

return ImmutableList.copyOf(someList);

и

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

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

...