Может ли класс в Java быть неизменным, если у него есть закрытый метод мутатора? - PullRequest
0 голосов
/ 18 сентября 2018

Итак, я где-то читал, что существует три требования для того, чтобы класс был неизменяемым в Java.

  1. Все поля данных должны быть закрытыми.
  2. Не может быть никакихметоды-мутаторы для полей данных.
  3. Никакие методы доступа не могут возвращать ссылку на поле данных, которое является изменяемым.

Но я не согласен с # 2, потому что даже если классимеет методы мутатора, он может быть неизменным, пока эти методы мутатора являются частными.Я прав или нет?Вы можете объяснить подробно?

Ответы [ 7 ]

0 голосов
/ 18 сентября 2018

На самом деле какой смысл частным мутаторам?

Неизменяемый означает, что состояние объекта не может измениться каким-либо образом после его создания.Не имеет значения, является ли это прямым доступом к полям, мутаторами или другим «случайным» методом, который изменяет состояние.Ничто из этого не допускается, чтобы класс был неизменным.

0 голосов
/ 18 сентября 2018

Существуют разные возможные определения неизменности.

Упомянутое вами определение не допускает каких-либо изменений состояния объекта.В частности, после того, как он был создан, он не может изменять свое собственное состояние.

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

Одним из преимуществ неизменяемых объектов, которое часто указывается, является то, что они автоматически поточно-ориентированы.Важно отметить, что это преимущество сохраняется только тогда, когда вы определяете неизменность строго (первый вариант выше).Если к объекту, который только изменяет свое ненаблюдаемое состояние, одновременно обращаются два потока, он в принципе все равно может давать ошибочные результаты, поэтому программист должен позаботиться о том, чтобы объект был потокобезопасным.

0 голосов
/ 18 сентября 2018

РЕДАКТИРОВАТЬ

Но я не согласен с # 2, потому что даже если в классе есть методы-мутаторы, он может быть неизменным, пока эти методы-мутаторы являются приватными

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

Неизменный имеет только геттер. Нет возможности изменить значение его полей после его установки.

Давайте возьмем String класс, он неизменен

Как только объект String создан, его нельзя изменять. Его нельзя увеличить или уменьшить, и вы не можете изменить один из символов внутри него. Вы можете думать о струне как о ящике для хранения, который у вас полностью заполнен, и чьи стороны не могут выпячиваться. Нет никакого способа добавить объекты, и вы не можете заменить объекты, не нарушая все расположение.

так что неизменность класса должна быть такой.

0 голосов
/ 18 сентября 2018

Да, для полей данных не может быть методов-мутаторов.

Причина в том, что установка метода private влияет только на область действия метода.Если вы хотите действительно неизменяемую переменную, вы должны также установить переменную final.Таким образом, ваша переменная не может быть изменена.

0 голосов
/ 18 сентября 2018

Непосредственно взято из Википедии:

В объектно-ориентированном и функциональном программировании неизменный объект (неизменяемый объект) - это объект, состояние которого нельзя изменить после его создания.

Так что определенно, если у вас есть класс с методом мутатора, который изменяет состояние объекта (предназначенного как экземпляр класса), тогда этот класс не является неизменным. Чтобы считать его неизменным, каждый метод должен не изменять свое состояние, а создавать другой объект того же класса с примененной модификацией.

0 голосов
/ 18 сентября 2018

Неизменяемый не означает: другой класс не может изменить состояние этого объекта, это означает: состояние этого объекта никогда не может измениться.

Рассмотрим этот код:

public Person {

  private String name;

  public Person(String name) {

    this.name = name;

  }

  private void setName(String name) {
    this.name = name;
  }

  public boolean hasName(String name) {
    boolean result = this.name.equals(name);
    this.name = name;
    return result;
  }
}

Этот класс нельзя считать неизменным, поскольку даже если классу, вызывающему hasName(String name), это не кажется, состояние объекта изменяется.Видя, что обычно неизменный класс обычно имеет члены, объявленные как final, это даже не скомпилируется.

0 голосов
/ 18 сентября 2018

Есть и другие способы сломать ваш неизменный объект.Например, API отражения.Я полагаю, что если вы решили сделать его неизменным, не могли бы вы стереть метод приватного сеттера.Просто не имеет смысла держать его там.

...