(нет) Свойства в Java?
Итак, до недавнего времени я умышленно держал Java n00b, и моя первая реальная экспозиция вызвала небольшой шок: у Java нет свойств стиля С#!
Хорошо, я могу жить с этим. Тем не менее, я также могу поклясться, что я видел код getter/setter в Java на одной базе кода, но я не могу вспомнить, где. Как это было достигнуто? Есть ли языковое расширение для этого? Связано ли это с NetBeans или что-то в этом роде?
Ответы
Ответ 1
Существует стандартный шаблон для геттеров и сеттеров в Java, называемый Bean свойства. В принципе, любой метод, начинающийся с get
, не принимающий аргументов и возвращающего значение, является атрибутом getter для свойства, называемого остальным именем метода (с буквой начала с буквой). Аналогично set
создает сеттер метода void с единственным аргументом.
Например:
// Getter for "awesomeString"
public String getAwesomeString() {
return awesomeString;
}
// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
this.awesomeString = awesomeString;
}
Большинство Java IDEs генерируют эти методы для вас, если вы спросите их (в Eclipse это так же просто, как перемещение курсора в поле и нажатие ctrl-1, а затем выбор опции из списка).
Для того, что стоит, для удобства чтения вы можете использовать is
и has
вместо get
для свойств типа boolean, например:
public boolean isAwesome();
public boolean hasAwesomeStuff();
Ответ 2
Я удивлен, что никто не упомянул проект lombok
Да, в настоящее время в java нет свойств. Есть и другие недостающие функции.
Но, к счастью, мы проект lombok, который пытается улучшить ситуацию. Он также становится все более популярным каждый день.
Итак, если вы используете ломбок:
@Getter @Setter int awesomeInteger = 5;
Этот код будет генерировать getAwesomeInteger
и setAwesomeInteger
. Таким образом, он очень похож на С# автоматически реализованные свойства.
Вы можете получить более подробную информацию о lombok getters и сеттерах здесь.
Вы должны обязательно проверить другие функции.
Мои фавориты:
Ломбок хорошо интегрирован с IDE, поэтому он будет показывать сгенерированные методы, например, если они существуют (предложения, содержимое класса, переход к декларации и рефакторинг).
Единственная проблема с ломбоком в том, что другие программисты могут не знать об этом. Вы всегда можете delombok код, но это скорее обходное решение, чем решение.
Ответ 3
public class Animal {
@Getter @Setter private String name;
@Getter @Setter private String gender;
@Getter @Setter private String species;
}
Это что-то вроде свойств С#. Это http://projectlombok.org/
Ответ 4
Соглашение bean заключается в написании кода следующим образом:
private int foo;
public int getFoo() {
return foo;
}
public void setFoo(int newFoo) {
foo = newFoo;
}
В некоторых других языках JVM, например, Groovy, вы получаете переопределяемые свойства, подобные С#, например,
int foo
к которому обращается простой .foo
и использует стандартные реализации getFoo
и setFoo
, которые вы можете переопределить по мере необходимости.
Ответ 5
"Поддержка свойств Java" была предложена для Java 7, но не попала в этот язык.
Смотрите http://tech.puredanger.com/java7#property для получения дополнительных ссылок и информации, если они заинтересованы.
Ответ 6
Большинство IDE для Java автоматически генерируют код getter и setter для вас, если вы хотите. Существует несколько различных соглашений, и IDE, например Eclipse, позволит вам выбрать, какой из них вы хотите использовать, и даже позволить вам определить свой собственный.
Eclipse даже включает автоматическое рефакторинг, который позволит вам обернуть свойство в getter и setter, и он изменит весь код, который обращается к этому свойству напрямую, чтобы использовать его с помощью getter и/или setter.
Конечно, Eclipse может только модифицировать код, о котором он знает, - любые внешние зависимости, которые у вас могут быть нарушены таким рефакторингом.
Ответ 7
Из книги Джеффри Рихтера CLR через С#: (Я думаю, что это могут быть причины, по которым свойства еще не добавлены в JAVA)
- Метод свойств может вызывать исключение; доступ к полю никогда не вызывает исключения.
- Свойство не может передаваться в качестве параметра
out
или ref
для метода; поле может.
- Метод свойств может занять много времени; доступ к полям всегда завершается
немедленно. Общей причиной использования свойств является выполнение синхронизации потоков,
который может остановить поток навсегда, и, следовательно, свойство не должно быть
используется, если требуется синхронизация потоков. В этой ситуации предпочтительным является метод.
Кроме того, если ваш класс можно получить удаленно (например, ваш класс
System.MarshalByRefObject
), вызов метода свойства будет очень медленным, и
поэтому предпочтительным является способ. На мой взгляд, классы, полученные из
MarshalByRefObject
никогда не должен использовать свойства.
- Если вы вызываете несколько раз подряд, метод свойств может возвращать другое значение каждый
время; поле возвращает одно и то же значение каждый раз. Класс
System.DateTime
имеет только чтение
Now
свойство, которое возвращает текущую дату и время. Каждый раз, когда вы запрашиваете это
свойство, оно вернет другое значение. Это ошибка, и Microsoft хочет, чтобы
они могут исправить класс, сделав теперь метод вместо свойства. Environment
s
Свойство TickCount
- еще один пример этой ошибки.
- Метод свойств может вызвать наблюдаемые побочные эффекты; доступ к полю никогда не выполняется. В других
слова, пользователь типа должен иметь возможность устанавливать различные свойства, определенные типом в
любой заказ, который он или она выбирает, не замечая какого-либо другого поведения в типе.
- Метод свойств может потребовать дополнительной памяти или вернуть ссылку на что-то
который фактически не является частью состояния объектов, поэтому для изменения возвращаемого объекта нет
воздействие на исходный объект; запрос поля всегда возвращает ссылку на объект
который гарантированно станет частью состояния исходных объектов. Работа с имуществом
который возвращает копию, может быть очень запутан для разработчиков, и эта характеристика часто
не документированы.
Ответ 8
Вам может не понадобиться префикс "получить" и "установить", чтобы он выглядел скорее как свойства, вы можете сделать это следующим образом:
public class Person {
private String firstName = "";
private Integer age = 0;
public String firstName() { return firstName; } // getter
public void firstName(String val) { firstName = val; } // setter
public Integer age() { return age; } // getter
public void age(Integer val) { age = val; } //setter
public static void main(String[] args) {
Person p = new Person();
//set
p.firstName("Lemuel");
p.age(40);
//get
System.out.println(String.format("I'm %s, %d yearsold",
p.firstName(),
p.age());
}
}
Ответ 9
Мой опыт Java не так уж и высок, поэтому каждый может меня исправить. Но AFAIK, общая конвенция, состоит в том, чтобы написать два метода:
public string getMyString() {
// return it here
}
public void setMyString(string myString) {
// set it here
}
Ответ 10
Если вы используете eclipse, тогда у него есть возможности автоматически генерировать метод getter и setter для внутренних атрибутов, это может быть полезным и экономичным инструментом.
Ответ 11
Я просто выпускаю аннотации Java 5/6 и обработчик аннотации, чтобы помочь в этом.
Отъезд http://code.google.com/p/javadude/wiki/Annotations
Документация немного освещена прямо сейчас, но quickref должен получить эту идею.
В основном он генерирует суперкласс с геттерами/сеттерами (и многими другими вариантами генерации кода).
Класс образца может выглядеть как
@Bean(properties = {
@Property(name="name", bound=true),
@Property(name="age,type=int.class)
})
public class Person extends PersonGen {
}
Имеется много других доступных образцов, и в сгенерированном коде нет зависимостей во время выполнения.
Пришлите мне письмо, если вы попробуете его и сочтете это полезным!
- Скотт
Ответ 12
И помните: если вы кодируете или используете классы, у которых есть только сеттеры и геттеры, вы не выполняете объектно-ориентированную разработку, и вам, вероятно, не стоит заботиться о производительности. Они называются структурами и являются неотъемлемой частью структурированного процедурного программирования примерно в конце 1980-х годов.
Объекты, как правило, не имеют ни одного или очень мало сеттеров и ни одного, ни очень небольшого количества геттеров. Большинство методов будут выполнять фактическую функциональность, связанную с классом, в котором они находятся. Чтобы визуализировать разницу, рассмотрите bean с 10 сеттерами и объектом, имеющим метод load(). Один поощряет инкапсуляцию и поэтому будет более понятным и более простым в обслуживании - другой зависает на углу улицы и может и используется кем угодно и где угодно.
ДОПОЛНИТЕЛЬНО: для тех из вас, кто спорит с этим, потому что вы где-то читаете, что наличие функциональности в ваших сущностях плохо, тогда я предлагаю это простое решение - обернуть (не копировать) экземпляр объекта в классе домена. Это сочетает код (класс домена) с данными (сущностью), так что целое теперь является истинным объектом. Поместите всю функциональность, которая работает с данными сущности в классе домена - сделав это, ни один другой класс не должен нуждаться в общем доступе к сущности, поэтому не выставляйте эти элементы и наборы, только открывайте функциональные возможности.