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

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

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


person Ishmaeel    schedule 16.09.2008    source источник


Ответы (14)


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

Например:

// 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();
person Calum    schedule 16.09.2008
comment
Я могу поклясться, что где-то видел синтаксис свойств в стиле C# в каком-то Java-коде, но хоть убей, не могу вспомнить, где и как. Это действительно не отвечает на мой вопрос, но я приму это за фактор удивительности. Возможно, тогда у меня были галлюцинации. - person Ishmaeel; 16.09.2008
comment
Я почти уверен, что это невозможно сделать на Java, извините. Однако есть много языков JVM, которые имеют первоклассную поддержку для такого рода вещей, может быть, это то, что вы видели? - person Calum; 16.09.2008
comment
Является ли нарушением этого соглашения, если вы ставите перед переменной-членом что-то вроде m, m_ или _, но не включаете этот префикс в имя свойства? - person Panzercrisis; 03.09.2014

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

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

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

@Getter @Setter int awesomeInteger = 5;

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

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

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

person Aleks-Daniel Jakimenko-A.    schedule 28.08.2013
comment
наличие методов, которые вы не видите в коде, кажется еще хуже. Автосвойства в С# — это только половина дела — в основном речь идет об именовании и группировке связанной логики. - person JonnyRaa; 12.05.2014
comment
@JonnyLeeds ну как это вообще плохо? Вы можете увидеть их в коде, заметив аннотации @Getter и @Setter, и они также отображаются на других панелях инструментов (например, наброски или предложения). - person Aleks-Daniel Jakimenko-A.; 14.05.2014
comment
Аннотации не наследуются, тем самым ограничивая вашу способность заниматься объектно-ориентированной разработкой. Если вы занимаетесь объектно-ориентированным программированием, то вы знаете, что очень мало причин даже иметь геттеры и сеттеры. Гораздо лучше раскрывать поведение, а не модель данных. Мы вышли далеко за рамки того, где кто-либо должен использовать структуры (bean-компоненты). - person Rodney P. Barbati; 14.11.2017

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

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

person Cheekysoft    schedule 16.09.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, которые вы можете переопределить по мере необходимости.

person Hank Gay    schedule 16.09.2008

public class Animal {

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

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

person dantuch    schedule 28.08.2013
comment
Обратите внимание: это будет считаться расширением языка и может сильно запутать IDE. - person millimoose; 28.08.2013
comment
@millimoose Вам просто нужен плагин для IDE. К сожалению, он нужен всем, кто использует такой код. - person dantuch; 28.08.2013
comment
Нужен плагин для IDE, хочется свернуть газету и прихлопнуть ответственного за это человека. (Хотя, возможно, это больше в случаях, когда конфигурация IDE является основной системой сборки для кодовой базы.) - person millimoose; 28.08.2013

Вам могут не понадобиться префиксы «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());
    }
}
person LEMUEL ADANE    schedule 28.01.2015

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

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

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

person Bill Michell    schedule 16.09.2008

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

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

public void setMyString(string myString) {
    // set it here
}
person Mark Embling    schedule 16.09.2008

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

  • Метод свойства может вызвать исключение; доступ к полю никогда не вызывает исключения.
  • Свойство нельзя передать методу как параметр out или ref; поле может.
  • Выполнение метода свойства может занять много времени; доступ к полю всегда завершается немедленно. Распространенной причиной использования свойств является выполнение синхронизации потоков, которая может остановить поток навсегда, поэтому свойство не следует использовать, если требуется синхронизация потоков. В этой ситуации метод предпочтительнее. Кроме того, если к вашему классу можно получить доступ удаленно (например, ваш класс является производным от System.MarshalByRefObject), вызов метода свойства будет очень медленным, и поэтому метод предпочтительнее свойства. На мой взгляд, классы, производные от MarshalByRefObject, никогда не должны использовать свойства.
  • Если метод свойства вызывается несколько раз подряд, он может каждый раз возвращать другое значение; поле каждый раз возвращает одно и то же значение. Класс System.DateTime имеет свойство Now только для чтения, которое возвращает текущую дату и время. Каждый раз, когда вы запрашиваете это свойство, оно возвращает другое значение. Это ошибка, и Microsoft хочет исправить класс, сделав Now методом, а не свойством. Свойство TickCount объекта Environment — еще один пример этой ошибки.
  • Метод свойств может вызвать наблюдаемые побочные эффекты; доступ к полю никогда не делает. Другими словами, пользователь типа должен иметь возможность устанавливать различные свойства, определенные типом, в любом порядке, который он выбирает, не замечая никакого другого поведения в типе.
  • Метод свойства может потребовать дополнительной памяти или вернуть ссылку на что-то, что на самом деле не является частью состояния объекта, поэтому изменение возвращаемого объекта не влияет на исходный объект; запрос поля всегда возвращает ссылку на объект, который гарантированно является частью исходного состояния объекта. Работа со свойством, возвращающим копию, может сильно запутать разработчиков, и эта характеристика часто не документируется.
person th1rdey3    schedule 26.12.2013
comment
Это ошибка, и Microsoft хочет, чтобы они могли исправить класс, сделав Now методом вместо свойства. Есть ли где-нибудь доказательства этого? Попробуйте заменить все свойства слов на методы получения и установки и прочитайте еще раз. Текст по-прежнему должен быть точным, и именно поэтому я нахожу такие аргументы глупыми. На мой взгляд, это просто я не понимаю, что такое свойство, поэтому оно мне не нравится... Ну, свойство - это просто дружественный синтаксис для методов получения и установки... Так что, если вам не нравятся свойства , то вам не должны нравиться геттеры и сеттеры... - person Jens; 09.10.2017

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

person TK.    schedule 16.09.2008


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

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
person Patrick PIGNOL    schedule 17.02.2018

Как упоминалось ранее для eclipse, интегрированная среда разработки (IDE) часто может автоматически создавать методы доступа.

Вы также можете сделать это с помощью NetBeans.

Чтобы создать методы доступа для вашего класса, откройте файл класса, затем щелкните правой кнопкой мыши в любом месте редактора исходного кода и выберите команду меню Refactor, Encapsulate Fields. Откроется диалоговое окно. Нажмите «Выбрать все», затем нажмите «Рефакторинг». Вуаля,

Удачи,

person Mario Levesque    schedule 06.01.2019

Для меня проблема состоит из двух частей:

  1. Все эти дополнительные методы {get*/set*} загромождают код класса.
  2. НЕ иметь возможности обращаться с ними как со свойствами:
    public class Test {
      private String _testField;

      public String testProperty {
       get {
        return _testField;
       }
       set {
        _testField = value;
       }
      }
    }

    public class TestUser {
      private Test test;

      public TestUser() {
        test = new Test();

        test.testProperty = "Just something to store";
        System.out.printLn(test.testProperty);
      }
    }

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

Я думаю, что проблема также в ненужном беспорядке в коде, а не в «сложности» создания сеттеров/геттеров. Я считаю их уродливым кодом. Мне нравится то, что есть в C#. Я не понимаю сопротивления добавлению этой возможности в Java.

Мое текущее решение состоит в том, чтобы использовать «общедоступные» члены, когда защита не требуется:

public class IntReturn {
    public int val;
}

public class StringReturn {
    public String val;
}

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

StringReturn sRtn = new StringReturn()

if(add(2, 3, sRtn)){
    System.out.println("Value greater than zero");
}

public boolean add(final int a, final int b, final StringReturn sRtn){
    int rtn = a + b;
    sRtn.val = "" + rtn;
    return rtn > 0; // Just something to use the return for.
}

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

Если ваша информация передается как «неизменяемая», то решением может стать новая запись Java. Однако он по-прежнему использует методологию установки/получения, только без префиксов установки/получения.

person Bradley Willcott    schedule 28.11.2019