Java Setter и Getter

Всегда рекомендуется использовать getter/setter для доступа к частным переменным. Почему бы не лучше объявить их публичными и получить к ним доступ. В любом случае мы обращаемся к нему с помощью getter и setter?

Ответы

Ответ 1

@mre ответ отличный, и ваш вопрос является основополагающим. Подводя итог: вы помещаете поля частного объекта, чтобы получить контроль над тем, как он будет использоваться другими объектами. Ваш объект использует setter для:

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

он будет использовать getter для

  • форматировать данные на выходе по желанию клиента
  • управлять последовательностью служб (например, он будет предоставлять данные тогда и только тогда, когда соединение установлено)

Добро пожаловать в чудесный мир программирования OO и магию структурированного программирования.

Stéphane

Ответ 2

Герметизация.

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

См. также:

Ответ 3

Все ответы выше превосходны, но позвольте мне добавить еще один момент.

Вы не хотите, чтобы все ваши личные переменные имели публичные получатели и сеттеры.

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

Ответ 4

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

public int getInt() { return _someInt;}

но может закончиться как

public int getInt() { 
  // do some processing
  return _someInt;

}

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

Ответ 5

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

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

Ответ 6

Все остальные ответы велики и очень верны. Вот еще одна причина, по которой я нашел ее полезной.

Использование геттеров и сеттеров на объекте является самой большой частью следующего соглашения JavaBean. Хотя последующее его письмо часто бывает затруднительным и чрезмерным, по крайней мере многие сторонние структуры/библиотеки/языки выражений зависят от соглашения getters и seters для доступа к полям объекта. Если вы будете следить за ним, вы уже можете использовать объекты с этими другими очень полезными библиотеками, не обновляя свои объекты.

Примеры, которые я использовал, включают:

  • Jsp
  • Freemarker
  • jXls
  • Spring (хотя Spring настолько устойчив, что вам не обязательно следовать соглашению)
  • SpEL (действительно любой язык выражения)

Ответ 7

Я использую регулярно геттер и сеттер, но, видимо, мы не делаем это правильно. Например: (полученное из http://java.dzone.com/articles/java-properties-without)

с геттером и сеттером (путь длинный)

public class Teacher {

 @Id @Column(length=5) @Required 
 private String id;

 @Column(length=40) @Required
 private String name;

 @OneToMany(mappedBy="teacher")
 private Collection pupils;

 public String getId() {
     return id;
 }

 public void setId(String id) {
     this.id = id;
 }

 public String getName() {
     return name;
 }

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

 public Collection getPupils() {
     return pupils;
 }

 public void setPupils(Collection pupils) {
     this.pupils = pupils;
 }

}

с публикацией: (всего 13 строк, подсчет пустых строк).

@Entity
public class Teacher {

 @Id @Column(length=5) @Required 
 public String id;

 @Column(length=40) @Required
 public String name;

 @OneToMany(mappedBy="teacher")
 public Collection pupils;

}

вызов с помощью getter и setter (не совсем понятно, однако С# делает его более чистым).

teacher.setName("M. Carmen");
String result = teacher.getName();

вызов public (прямой и чистый).

teacher.name = "M. Carmen";
String result = teacher.name;

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

В некоторых случаях обязательно использовать setter и getter, но если нет, то я думаю, что это немного перебор, чтобы использовать его по умолчанию.