(нет) свойства в Java? - PullRequest
       35

(нет) свойства в Java?

54 голосов
/ 16 сентября 2008

Итак, я до недавнего времени умышленно оставлял себе Java n00b, и мое первое настоящее знакомство вызвало небольшой шок: у Java нет свойств стиля C #!

Хорошо, я могу жить с этим. Тем не менее, я также могу поклясться, что видел код getter / setter свойства в Java в одной кодовой базе, но я не могу вспомнить где. Как это было достигнуто? Есть ли для этого расширение языка? Это связано с NetBeans или с чем-то еще?

Ответы [ 13 ]

62 голосов
/ 16 сентября 2008

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

Например:

// Getter for "awesomeString"
public String getAwesomeString() {
  return awesomeString;
}

// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
  this.awesomeString = awesomeString;
}

Большинство Java IDE генерируют эти методы для вас, если вы спросите их (в Eclipse это так же просто, как переместить курсор в поле и нажать Ctrl-1, а затем выбрать опцию из списка).

Что бы это ни стоило, для удобства чтения вы можете использовать is и has вместо get для свойств логического типа, например:

public boolean isAwesome();

public boolean hasAwesomeStuff();
32 голосов
/ 28 августа 2013

Я удивлен, что никто не упомянул проект ломбок

Да, в настоящее время в java нет свойств. Также есть некоторые другие недостающие функции.
Но, к счастью, у нас есть проект ломбок , который пытается улучшить ситуацию. Он также становится все более популярным с каждым днем.

Итак, если вы используете ломбок:

@Getter @Setter int awesomeInteger = 5;

Этот код также будет генерировать getAwesomeInteger и setAwesomeInteger. Так что это очень похоже на автоматически реализованные свойства C # .

Вы можете получить более подробную информацию о геттерах и установщиках Ломбока здесь .
Вы должны обязательно проверить другие функции . Мои любимые:

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

7 голосов
/ 16 сентября 2008

«Поддержка свойств Java» была предложена для Java 7, но не была переведена на язык.

См. http://tech.puredanger.com/java7#property для дополнительных ссылок и информации, если интересно.

6 голосов
/ 28 августа 2013
public class Animal {

    @Getter @Setter private String name;
    @Getter @Setter private String gender;
    @Getter @Setter private String species;
}

Это что-то вроде свойств C #. Это http://projectlombok.org/

6 голосов
/ 16 сентября 2008

Соглашение bean-компонента заключается в написании кода, подобного следующему:

private int foo;
public int getFoo() {
    return foo;
}
public void setFoo(int newFoo) {
    foo = newFoo;
}

В некоторых других языках JVM, например, Groovy, вы получаете переопределяемые свойства, подобные C #, например,

int foo

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

4 голосов
/ 28 января 2015

Вам могут не понадобиться префиксы «get» и «set», чтобы они больше походили на свойства, вы можете сделать это так:

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());
    }
}
3 голосов
/ 26 декабря 2013

Из книги Джеффри Рихтера CLR через C # : (я думаю, это могут быть причины, по которым свойства все еще не добавлены в JAVA)

  • Метод свойства может вызвать исключение; доступ к полю никогда не вызывает исключение.
  • Свойство не может быть передано в качестве параметра out или ref методу; поле может.
  • Метод свойства может занять много времени; доступ к полю всегда завершается немедленно. Распространенной причиной использования свойств является синхронизация потоков, который может остановить поток навсегда, и, следовательно, свойство не должно быть используется, если требуется синхронизация потоков. В этой ситуации метод является предпочтительным. Кроме того, если ваш класс может быть доступен удаленно (например, ваш класс является производным от System.MarshalByRefObject), вызов метода свойства будет очень медленным, и поэтому метод предпочтительнее свойства. На мой взгляд, классы, полученные из MarshalByRefObject никогда не следует использовать свойства.
  • Если вызывается несколько раз подряд, метод свойства может возвращать разные значения каждый время; поле возвращает одно и то же значение каждый раз. System.DateTime класс имеет только для чтения Now свойство, которое возвращает текущую дату и время. Каждый раз, когда вы запрашиваете это свойство, он вернет другое значение. Это ошибка, и Microsoft желает, чтобы они могли бы исправить класс, сделав метод Now вместо свойства. Environment s Свойство TickCount является еще одним примером этой ошибки.
  • Метод свойств может вызывать наблюдаемые побочные эффекты; доступ к полю никогда не делает. В других словами, пользователь типа должен иметь возможность устанавливать различные свойства, определенные типом в любой порядок, который он или она выбирает, не замечая никакого другого поведения в типе.
  • Метод свойства может потребовать дополнительной памяти или вернуть ссылку на что-то это на самом деле не является частью состояния объекта, поэтому изменение возвращаемого объекта не имеет влияние на исходный объект; запрос поля всегда возвращает ссылку на объект это гарантированно является частью состояния исходного объекта. Работа с собственностью то, что возвращает копию, может быть очень запутанным для разработчиков, и эта характеристика часто не задокументировано.
3 голосов
/ 16 сентября 2008

Большинство IDE для Java автоматически генерируют для вас код получения и установки, если вы этого хотите. Существует ряд различных соглашений, и IDE, такая как Eclipse, позволит вам выбрать, какую из них вы хотите использовать, и даже позволит вам определить свою собственную.

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

Конечно, Eclipse может модифицировать только тот код, о котором он знает - любые внешние зависимости, которые у вас есть, могут быть нарушены таким рефакторингом.

2 голосов
/ 16 сентября 2008

Мой опыт работы с Java не так уж и высок, поэтому любой может смело поправлять меня. Но AFAIK, общее соглашение состоит в том, чтобы написать два метода следующим образом:

public string getMyString() {
    // return it here
}

public void setMyString(string myString) {
    // set it here
}
1 голос
/ 17 февраля 2018

В java нет ключевого слова свойства (как вы могли бы найти его в C #), ближайший способ получить 1 слово getter / setter - сделать как в C ++:

public class MyClass
{
    private int aMyAttribute;
    public MyClass()
    {
        this.aMyAttribute = 0;
    }
    public void mMyAttribute(int pMyAttributeParameter)
    {
        this.aMyAttribute = pMyAttributeParameter;
    }
    public int mMyAttribute()
    {
        return this.aMyAttribute;
    }
}
//usage :
int vIndex = 1;
MyClass vClass = new MyClass();
vClass.mMyAttribute(vIndex);
vIndex = 0;
vIndex = vClass.mMyAttribute();
// vIndex == 1
...