Подтвердить что ты не робот

Лучшая практика для именования параметров в конструкторах Java и простых сеттерах

Существует ли стандартное приемлемое соглашение для параметров в Java для простых конструкторов и сеттеров?

(Я видел ответ на С++, но практика часто отличается между двумя сообществами)

Предположим, что у меня есть класс C с полем foo.

Я обычно видел следующие три варианта:

1) Используйте имя фактического поля с подчеркиванием:

public C(Type foo_)
{
   foo = foo_;
}

public void setFoo(Type foo_)
{
   foo = foo_;
}

2) Используйте фактическое имя поля, просто используйте "this" в настройке:

public C(Type foo)
{
   this.foo = foo;
}
public void setFoo(Type foo)
{
   this.foo = foo;
}

3) Полностью непоследовательные вещи вроде:

public C(Type bar)
{
   this.foo = bar;
}
public void setFoo(Type bar)
{
   this.foo = bar;
}

Я имею тенденцию использовать 2, но мне интересно, какая правильная практика.

4b9b3361

Ответ 1

Вариант второй является наиболее распространенным. В Java рассматривалась плохая практика использования бессмысленных префиксов имен или суффиксов для различения переменных экземпляра из параметров из локальных переменных. Но для самих имен нет никаких соглашений. Используйте любые имена, чтобы код легче всего понять.

Ответ 2

Я также видел вариант 2 как наиболее распространенный:

int importance;

public int getImportance()
{
    return importance;
}

public void setFoo(int importance)
{
    this.importance = importance;
}

IDE, такие как Eclipse и Netbeans, автоматически записывают геттеры и сеттеры в вышеуказанном формате.

Для использования этого метода существует несколько достоинств:

Не использовать символ подчеркивания (_) в имени поля - подчеркивания не рекомендуются для непостоянных имен полей.

Использование символа подчеркивания в идентификаторе не рекомендуется, кроме идентификаторов для констант.

Страница Variables в учебниках Java упоминает следующее о символах подчеркивания:

Если ваша переменная хранит константу значение, например static final int NUM_GEARS = 6, изменения конвенции слегка, используя каждую букву и разделение последующих слов на символ подчеркивания. По конвенция, символ подчеркивания никогда не используется в других местах.

(Акцент добавлен.)

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

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

Ниже приведен пример автоматически созданного Javadoc:

/**
 *
 * @param importance  <-- Parameter name in Javadoc matches
 *                        the parameter name in the code.
 */
public void setImportance(int importance)
{
    this.importance = importance;
}

Наличие Javadoc отражает название поля, имеет другое преимущество - IDE, которые имеют завершение кода, могут использовать имя поля в Javadoc, чтобы автоматически заполнить имена параметров:

// Code completion gives the following:
this.getImportance(importance);

Придание значения имени поля и имени параметра упростит понимание того, что представляет собой параметр.

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

Ответ 3

(1) очень C/С++. Java не имеет тенденций часто использовать подчеркивания.

Я лично использую (2) почти исключительно.

(3) просто усложняет вашу жизнь, потому что трудно представить себе два значимых, но сжатых имени члена и параметра.

Ответ 4

Я видел, что 2 и 3 использовали больше всего. Тем не менее, ответ продиктован принятым стандартом для базы кода, в которую вы вносите. Я думаю, что более важно быть последовательным в проекте, чем иметь один "правильный" ответ для каждого разработчика Java.

Для генерации кода Eclipse используется стиль # 2 из вашего списка.

Ответ 5

Я знаю, что когда netbeans автоматически создает геттеры и сеттеры, он использует метод номер 2. Я лично обычно добавляю temp к переменной i.e foo = tempfoo. Но поскольку neesh говорит, что вы должны стараться оставаться последовательными независимо от того, какой метод вы выберете

Ответ 6

Да вариант 2 наиболее широко используется; хотя у него есть серьезная проблема: если у вас есть опечатка в объявлении вашего параметра - это может остаться незамеченным из-за затенения, например:

class Whatever { 
  String val;
  Whatever(String va1) { this.val = val; }
  void printMe() { System.out.println(val.toString()); }
  public static void main(String[] args) {
    new Whatever("Hello").printMe();
  }
}

Этот код компилируется отлично; и вам понадобится секунда, чтобы понять, что там не так. Если у вас есть сомнения; просто распечатайте его; отнесите его своим коллегам и спросите их, что произойдет, если этот класс будет скомпилирован и выполнен. Мое предположение: 75% + будет не понимать, что будет выбрано исключение NullPointerException. И если вы перейдете к шрифту, который "выглядит одинаковым" для val и va1; то никто не заметит из чтения...

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

Но: если вы избежите этого шаблона и используете префиксы или "thisString", вы никогда не столкнетесь с этой проблемой в первую очередь. Таким образом, я действительно не понимаю, почему это так часто используется.

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

Ответ 7

Вариант 2 - это то, что рекомендуют большинство руководств по стилю Java.

Я нашел руководство по стилю Google Java довольно полезным:

обновленная ссылка (июнь-2019 г.): https://google.github.io/styleguide/javaguide.html

или поищите в Интернете "Руководство по стилю Google Java"

Ответ 8

Я лично использую foo(Bar parBar), хотя я знаю, что обычно считается неправильной практикой пред- или суффиксных имен переменных.

Причина этого довольно проста: Ясность

Теперь, если вы вызываете метод foo(Bar bar), это может быть не всегда интуитивным, что означает bar. И даже если это так, это все еще боль в прикладе.

Как this.bar = bar или даже bar = bar более чистый и интуитивно понятный, чем bar = parBar? У меня скорее префикс, чем логическая двусмысленность.

Ответ 9

Как вы код, чтобы сделать интерфейс настолько ясным, насколько это возможно, я всегда предпочитаю использовать поле _name внутренне, имея его как name как аргумент метода, назначая его элегантно как _name = name. Я видел это в Fowler Refactoring и других подобных учебниках, хотя я вижу уродливые механизмы, такие как использование поля как name внутри, а затем используя aName как аргумент метода, ugh.

Ответ 10

Вариант 2.

Если вы видите определение "setFoo (String foo)" (например, в javadoc или hover), вам было бы разумно ожидать, что поле "foo" будет установлено в значение параметра "foo". Другие имена могут потребовать двойной проверки - например, setName (String person) просто установил имя для человека или предпримет дополнительные действия (найдите имя в таблице лиц и т.д.)?.

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

...  foo = foo;

вместо

this.foo = foo;

который является самоназначением параметра, который ничего не делает. Современные компиляторы поймают это - современная IDE генерирует оператор this.foo = foo при создании сеттера для поля.

В Eclipse вы можете создать getter и setter для поля с Ctrl-1, когда курсор находится в соответствующем поле.

Ответ 11

соглашение, которое я использую, заключается в предисловии переменных-членов с m_; как в:

Строка m_foo;

Таким образом, очень ясно, какие переменные являются членами, а какие нет.

также, моя последняя компания предваряла все аргументы в методе с "the", как в:

public doFoo (String theKey, String theRandom) {

....

}

было очень легко не путать аргументы с внутренними переменными.

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

Ответ 12

Вариант 2 наиболее распространен в Java, но придирчивый Checkstyle не позволит вам использовать этот параметр, потому что имя локального var тени другого.

Из-за этого наиболее используйте следующее:

foo(int thatBar) { this.bar = thatBar; }

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

Злой человек может использовать эту информацию, чтобы лучше понять ваш класс, только взглянув на методы. Но для этого вы бы использовали obfuscator, который переименовывает все vars и т.д.

Ответ 13

Хотя возвращение void из сеттера является обычным делом, иногда полезно возвращать ссылку на экземпляр:

public class Foo {

    String value1, value2;

    public Foo setValue1(String value1) {
        this.value1 = value1;
        return this;
    }

    public Foo setValue2(String value2) {
        this.value2 = value2;
        return this;
    }
}

Это позволяет вам new Foo().setValue1("A").setValue2("B"); установки значений: new Foo().setValue1("A").setValue2("B");