Каков принятый стиль использования ключевого слова this в Java?

37

Я пришел из таких языков, как Python или Javascript (и других, которые менее объектно-ориентированы), и я пытаюсь улучшить свои рабочие знания Java, которые я знаю только поверхностно.

Считается ли плохой практикой всегда добавлять thisк текущим атрибутам экземпляра? Мне кажется более естественным писать

...
private String foo;

public void printFoo() {
    System.out.println(this.foo);
}
...

чем

...
private String foo;

public void printFoo() {
    System.out.println(foo);
}
...

поскольку это помогает мне отличать атрибуты экземпляра от локальных переменных.

Конечно, в таком языке, как Javascript, имеет смысл всегда использовать this, поскольку можно иметь больше вложений функций, следовательно, локальные переменные поступают из более крупных областей. В Java, насколько я понимаю, такое вложение невозможно (кроме внутренних классов), поэтому, вероятно, это не большая проблема.

В любом случае я бы предпочел использовать this. Будет ли это странно, а не идиоматично?

Andrea
источник
Мы используем инструмент для стандартизации этого в нашей компании. Инструмент переписать код с нашим без этого в зависимости от политики компании. Так что каждый кодирует, как ему нравится, и код отформатирован правильно во время коммита.
Deadalnix
2
«поскольку можно иметь больше вложенных функций, следовательно, локальные переменные поступают из больших областей». Кроме того, тот факт, что «this» на самом деле не является одним из мест, откуда может быть неквалифицированная переменная в функции в JS.
Random832 10.10.11
2
Я префикс всех переменных экземпляра с подчеркиванием, чтобы я мог легко определить разницу между локальными и переменными экземпляра без использования this.
WuHoUnited
4
В C # StyleCop хочет, чтобы вы указывали this.при обращении к переменным-членам, методам и т. Д. Мне это нравится, я согласен с этим правилом. Я думаю, что это лучше, чем называть что-то символом подчеркивания в начале. Я бы следовал тому же правилу, если бы я кодировал в Java.
Работа

Ответы:

40

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

Это действительно довольно избыточно.

DeadMG
источник
7
Также: нормальная IDE должна визуально отличать поля и локальные переменные / параметры. Например, в Eclipse (по умолчанию) поля отображаются синим цветом, а локальные переменные - черным.
Йоахим Зауэр
1
@Joachim Замечательно, Eclipse может даже по-разному окрашивать параметры и локальные переменные по желанию пользователя (однако это не по умолчанию).
Эрик-Карл
3
Хотя я согласен, когда сталкиваюсь с кодом других разработчиков (и, будучи на первый взгляд незнакомым), я нахожу this.гораздо более полезным. Это также возможно потому, что у меня нет IDE, который по-разному кодирует локальные / объектные переменные.
Брэд Кристи
3
+1 за (перефразировать) «рефакторинг, если вам нужно использовать это, чтобы сделать вывод, что это член». Как раз то, что я хотел указать.
Ям Маркович
Я не нахожу, что это затрудняет чтение, и, в свою очередь, код остается читаемым в редакторах, которые имеют менее сложную подсветку синтаксиса, которая не различает поля и локальные объекты. У меня всегда было мнение, что вы должны стремиться к тому, чтобы ваш код был легко читаемым в самом простом текстовом редакторе, и если это не так, на это должна быть веская причина.
Кевин
26

Я предпочитаю использовать this. Это облегчает чтение кода в различных редакторах, которые окрашивают локальные переменные и переменные экземпляра одинаково. Это также облегчает чтение кода на печатной странице во время чего-то вроде проверки кода. Это также довольно сильное напоминание о сфере действия переменной другим разработчикам.

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

Я считаю, что последнее предложение ChrisF является мертвым: будьте последовательны в вашем использовании.

Томас Оуэнс
источник
7
«Это также довольно убедительное напоминание о сфере действия переменной другим разработчикам». - причину, которую я склонен использовать и люблю видеть this.в коде. Написание занимает полсекунды и может сэкономить долгие минуты, когда нужно выяснить, действительно ли парень, который раньше вас хотел использовать свойство pascal-case вместо local-case local, когда он сделал этот последний всплеск изменений 20 ревизий назад.
scrwtp
18

Единственное место, где я последовательно использую 'this' - это сеттеры и / или конструкторы:

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

Кроме этого, я не чувствую необходимости добавлять это. При чтении тела метода параметры и локальные параметры находятся прямо здесь - и их довольно легко отслеживать (даже без помощи IDE). Локальные данные и поля, как правило, имеют различную природу (состояние объекта или временное хранилище или параметр).

Если есть какая-то путаница относительно того, что такое переменная и что такое поле, это, вероятно, означает, что метод имеет слишком много переменных / параметров, слишком длинный и слишком сложный, и его следует упростить.

Если вы решите использовать «this» для пометки полей, я бы порекомендовал убедиться, что соглашение всегда строго соблюдается - начать было бы действительно легко, если предположить, что «this» не означает, что это локальный код, основанный на предположениях.

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

public boolean isSame(MyClass that) {
    return this.uuid().equals(that.uuid());
}
ptyx
источник
8

Это спорный вопрос.

Взяв C # в качестве аналогии, поскольку он имеет очень похожий синтаксис и структуру с Java, мы находим, что C # StyleCop имеет правило по умолчанию, которое требует добавления this, но ReSharper имеет правило по умолчанию, которое говорит, что thisэто избыточно (что это такое) и может быть удален.

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

Однако, что означают правила, так это то, что вы последовательны в своем использовании - что, пожалуй, самое важное.

ChrisF
источник
8

Считается ли плохой практикой всегда добавлять это к текущим атрибутам экземпляра?

Да - некоторыми, нет - другими.

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

Андрей Таптунов
источник
7

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

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

Я думаю, что «это» просто загромождает код. Особенно в современных IDE, которые по-разному окрашивают локальные параметры / локальные переменные / поля.

Эрик-Карл
источник
5

Я думаю, что вы ответили на свой вопрос с этим:

Мне кажется более естественным писать

... this.foo ...

чем

... фу ...

поскольку это помогает мне отличать атрибуты экземпляра от локальных переменных.

Если вам удобнее пользоваться this. , улучшая свои рабочие знания с Java, то во что бы то ни стало используйте эту вещь ( я думаю, что это, в некотором роде, знакомая сущность Python, к которой вы относитесь ).

Дело в том, что, хотя люди будут давать твердые / уместные аргументы об использовании или не использовании this., это по-прежнему звучит как дискуссия, например:

  • это делает назначение переменных ясным а вам следует переписать код, если неясно, что представляет собой каждая переменная;
  • this. избыточно, если вы проводите весь день в IDE а я выполняю обзоры кода и выполняю сравнения для разных версий, используя компаратор без подсветки синтаксиса;
  • не печатать this.дает мне важные миллисекунды производительности сравнению с тем, что мне this.платят нажатием клавиши, а добавление похоже на повышение зарплаты: D;
  • и т. д.

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


источник
5

Обычно добавлять это не нужно. Я не думаю, что это плохая практика как таковая, но чрезмерное использование этого , вероятно, будет считаться необычным в большинстве баз Java-кода, которые я видел.

Однако я нахожу это ценным в нескольких конкретных ситуациях:

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

class MyObject {
  int value;

  public MyObject(int value) {
    this.value=value;
  }
}

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

class MyObject {
  int value;
  ....

  public MyObject add(MyObject other) {
    return new MyObject( this.value + other.value )
  }
}
mikera
источник