Все ли финальные классы неизменны? - PullRequest
14 голосов
/ 27 октября 2009

Все конечные классы в Java неизменны. String и Integer оба являются окончательными классами, и оба неизменны, я верю.

Ответы [ 8 ]

30 голосов
/ 27 октября 2009

Нет, окончательный означает, что класс не может быть продлен. Это ничего не говорит о изменчивости. Например:

final class MutInt {
   public int modifyMe;
}
22 голосов
/ 27 октября 2009

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

public final class FinalMutable {
  int value;
  public void setValue(int v) { value=v; }
  public int getValue() { return value; }
}
9 голосов
/ 27 октября 2009

Нет ключевого слова для неизменности, это больше похоже на шаблон дизайна.

EDIT:
Это означает, что нет ключевого слова, которое делает класс неизменным. Чтобы сделать класс неизменным, вы должны защитить внутреннее устройство, сделав его окончательным или личным.

Смущает то, что ключевое слово final при использовании в классе имеет другое значение, чем при использовании в поле / переменной Первое означает «этот класс не может быть расширен». Второе означает «эту переменную (или ссылку) нельзя изменить».

5 голосов
/ 27 октября 2009

Как уже говорилось ранее, final не делает класс неизменяемым в Java, хотя он играет роль в стратегии неизменяемости. Чтобы получить неизменность, вы должны следовать общим правилам:

  • убедитесь, что класс не может быть переопределен - сделайте класс final или используйте статические фабрики и оставьте конструкторы закрытыми
  • сделать поля private и final
  • заставляет вызывающих полностью создать объект за один шаг, вместо использования конструктора без аргументов в сочетании с последующими вызовами setXXX методов (то есть, избегая соглашения Java Beans)
  • не предоставляют никаких методов, которые могут каким-либо образом изменить состояние объекта - не только setXXX методы, но и любой метод, который может изменить состояние
  • если у класса есть какие-либо изменяемые поля объекта, то они должны быть скопированы с защитой при передаче между классом и его вызывающей стороной
5 голосов
/ 27 октября 2009

В дополнение к другим ответам, если вы посмотрите на код для java.lang.String, вы увидите, что он содержит поле: hash, которое является изменяемым и фактически вычисляется и сохраняется, когда hashCode() вызывается впервые.

Однако класс по-прежнему неизменен : поле hash не может быть доступно напрямую или изменено вне класса.

Кроме того, вы можете заметить, что распространенным подходом в JDK является реализация неизменяемых оболочек, которые можно использовать для представления внутреннего состояния объекта, не допуская его изменения; например,

private final List<String> values;

public List<? get String> getValues() {
  return Collections.unmodifiableList(values);
}
2 голосов
/ 26 июля 2011

Закрытое поле не может быть доступно через переопределенные методы подкласса ... Таким образом, методы подкласса не могут изменить закрытое поле суперкласса ... Тогда какой смысл делать неизменяемый класс финальным

0 голосов
/ 05 февраля 2019

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

// a class not intended to be mutated 
public class GoodClass{

   private String name;

   public GoodClass() {
       this.name = "Good Class Neme";
   }

   public String getName() {
       return name;
   }
}

public class BadClass extends GoodClass {

   private String name;

   public String getName() {
       return name;
   }

   // mutating state
   public void setName(String name) {
       this.name = name;
   }
}



0 голосов
/ 05 июня 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...