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

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
56
0
52 835
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

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

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

public void setMyString(string myString) {
    // set it here
}

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

По соглашению bean-компонентов следует писать такой код:

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

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

int foo

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

Ответ принят как подходящий

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

Например:

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

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

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

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

public boolean isAwesome();

public boolean hasAwesomeStuff();

Могу поклясться, что я видел синтаксис свойств стиля C# где-то в каком-то Java-коде, но хоть убей, я не могу вспомнить, где и как. Это действительно не отвечает на мой вопрос, но я принимаю его из-за фактора удивительности. Возможно, тогда у меня были галлюцинации.

Ishmaeel 16.09.2008 13:41

Я почти уверен, что это невозможно сделать на Java, извините. Есть много языков JVM, которые имеют первоклассную поддержку для такого рода вещей, но, может быть, это то, что вы видели?

Calum 16.09.2008 14:41

Является ли нарушением этого соглашения префикс переменной-члена чем-то вроде m, m_ или _, но затем вы не включаете этот префикс в имя свойства?

Panzercrisis 03.09.2014 04:23

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

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

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

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

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

Я просто выпускаю аннотации Java 5/6 и процессор аннотаций, чтобы помочь в этом.

Проверить http://code.google.com/p/javadude/wiki/Annotations

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

В основном он генерирует суперкласс с геттерами / сеттерами (и многими другими вариантами генерации кода).

Примерный класс может выглядеть как

@Bean(properties = {
    @Property(name = "name", bound=true),
    @Property(name = "age,type=int.class)
})
public class Person extends PersonGen {
}

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

Напишите мне, если попробуете и найдете полезным! - Скотт

public class Animal {

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

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

Обратите внимание: это будет считаться расширением языка и может сильно сбивать с толку IDE.

millimoose 28.08.2013 23:47

@millimoose Вам просто нужен плагин для IDE. К сожалению, он нужен всем, кто использует такой код.

dantuch 28.08.2013 23:51

«Вам нужен плагин для IDE» заставляет меня свернуть газету и ударить человека, ответственного за это. (Хотя, возможно, это больше в тех случаях, когда конфигурация IDE является основной системой сборки для кодовой базы.)

millimoose 28.08.2013 23:54

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

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

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

@Getter @Setter int awesomeInteger = 5;

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

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

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

наличие методов, которые вы не видите в коде, кажется еще хуже. Автоматические свойства в C# - это только половина дела - в основном речь идет о логике именования и группировки.

JonnyRaa 12.05.2014 19:20

@JonnyLeeds хорошо, как это вообще плохо? Вы можете увидеть их в коде, заметив аннотации @Getter и @Setter, и они также отображаются на других панелях инструментов (например, в схеме или предложениях).

Aleks-Daniel Jakimenko-A. 14.05.2014 02:12

Аннотации не наследуются, что ограничивает вашу способность заниматься объектно-ориентированной разработкой. Если вы выполняете объектно-ориентированный подход, то вы знаете, что для создания геттеров и сеттеров очень мало причин. Намного лучше раскрыть поведение, чем модель данных. Мы далеко за пределами того, где кто-то должен использовать структуры (beans).

Rodney P. Barbati 14.11.2017 01:48

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

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

«Это ошибка, и Microsoft желает, чтобы они могли исправить класс, сделав Now методом вместо свойства» «Есть ли где-нибудь доказательства этого? Попробуйте заменить все слова «свойство» на «методы получения и установки» и прочтите еще раз. Текст должен быть точным, и поэтому я считаю такие аргументы глупыми. На мой взгляд, это просто «Я не понимаю, что такое Свойство, поэтому мне оно не нравится» ... Что ж, Свойство - это просто удобный синтаксис для методов получения и установки ... Так что, если вы не как свойства, то вам тоже не нравятся геттеры и сеттеры ...

Jens 09.10.2017 16:13

Возможно, вам не понадобятся префиксы «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());
    }
}

В java нет ключевого слова свойства (например, вы могли бы найти его в C#), ближайший способ получить одно слово 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

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

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

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

Удачи,

Для меня проблема двоякая:

  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 записывать может быть решением. Однако он по-прежнему использует методологию установки / получения, только без префиксов set / get.

Другие вопросы по теме