Защитное копирование в терминах ссылочного параметра в конструктор

Может кто-нибудь, пожалуйста, скажите мне, что такое защитное копирование с точки зрения ссылочного параметра в конструктор класса в JAVA

Спасибо оооочень большое

1 ответ

Решение

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

Давайте начнем с этого:

class NotSafeAtAll
{
    private final List<X> list;

    public NotSafeAtAll(final List<X> list)
    {
        this.list = list;
    }
}

Этот класс имеет огромную проблему: он копирует ссылку на список в качестве своего поля члена. Это означает, что если вызывающий конструктор изменяет этот список, изменения будут отражены в NotSafeAtAll экземпляр также.

И вот тут "оборонительное копирование" вступает в игру. Рассматривать:

class ALittleMoreSafe
{
    private final List<X> list;

    public ALittleMoreSafe(final List<X> list)
    {
        this.list = new ArrayList<X>(list);
    }
}

Теперь у класса есть своя копия списка; если вызывающая сторона изменяет список, который она передала в качестве аргумента конструктору, ALittleMoreSafe Экземпляр не будет затронут.

Но история на этом не заканчивается, конечно. Теперь рассмотрим, что в последнем классе есть метод, который возвращает список, полученный в качестве параметра:

class ALittleMoreSafe
{
    private final List<X> list;

    public ALittleMoreSafe(final List<X> list)
    {
        list = new ArrayList<X>(list);
    }

    public List<X> unsafeGetList()
    {
        return list;
    }
}

Ты проиграл! Даже если ваш конструктор безопасен, фактом является то, что вы возвращаете ссылку на свой внутренний список; и вызывающая сторона может изменить список с помощью этой ссылки.

Здесь опять защитная копия может спасти вас, но есть лучшее решение: убедитесь, что возвращаемый вами список неизменен:

public List<X> safeGetList()
{
    return Collections.unmodifiableList(list);
}

Любая попытка вызывающей стороны изменить возвращенный список потерпит неудачу.

Итак, история закончилась?

NO.

Это может быть закончено, только если все X экземпляры неизменны. К сожалению, очень классический и чрезмерно используемый шаблон bean-компонентов не гарантирует этого. Но это другая история.

Другие вопросы по тегам