Использование модификатора final, когда это применимо в Java

В Java существует практика объявления каждой переменной (локальной или классовой) параметром final, если они действительно есть.

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

Что вы думаете по этому поводу и за чем следите?

Это может привести к религиозному спору. Кому-то это нравится, кому-то это не нравится. Мне нравятся поля final, но не конечные локальные переменные, если они не нужны, не уверен, что это полностью рационально. Не уверен, что будет и голос "против". Я согласен с Алексом Миллером. ;)

Peter Lawrey 12.06.2009 00:25

Я могу понять, если людям не нравится, когда их код загроможден финалами. Но это проблема, которую мог бы решить хороший редактор: bugs.eclipse.org/bugs/show_bug.cgi?id=409379

oberlies 03.06.2013 12:23

связанные stackoverflow.com/questions/154314/when-should-one-use-final

Adrien Be 18.07.2013 11:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
198
3
63 717
25
Перейти к ответу Данный вопрос помечен как решенный

Ответы 25

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

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

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

Редактировать: В качестве пояснения (и попытки вернуть голоса против) я не говорю, что константы не помечаются как окончательные, я говорю, что не делайте таких вещей, как:

public String doSomething() {
  final String first = someReallyComplicatedExpressionToGetTheString();
  final String second = anotherReallyComplicatedExpressionToGetAnother();

  return first+second;
}

Это просто затрудняет чтение кода (на мой взгляд).

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

Переворачивая утверждение с ног на голову: я был в множество ситуаций, когда нет с использованием final (и неизменяемых объектов в целом) оказал существенное влияние на количество и влияние ошибок.

Chris Vest 26.09.2008 13:22

Я сторонник неизменяемых объектов, я просто никогда не был в ситуации, когда пометка неизменяемого объекта final мне помогла.

SCdF 27.09.2008 01:49

Я согласен с тем, что мы не должны использовать final для локальных переменных и параметров метода, это делает код намного менее читаемым.

rmaruszewski 17.03.2010 11:29

@ChrisVest, возможно, ваши функции слишком длинные

Pacerier 17.05.2020 16:31

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

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

Последнее слово о последнем ключевом слове

Я почти не использую final для методов или классов, потому что мне нравится позволять людям переопределять их.

В противном случае я использую только final, если это public/private static final type SOME_CONSTANT;

Хм .. отредактировано в одном месте .. все же сказано, наконец, во второй строке ;-)

Omnipotent 29.09.2008 09:21

Разрешение людям переопределять значения - один из самых больших источников сюрпризов и трудных для понимания ошибок.

RAY 01.03.2011 04:10

В Effective Java есть пункт «Отдавать предпочтение неизменяемым объектам». Объявление полей как final поможет вам сделать несколько небольших шагов в этом направлении, но, конечно, действительно неизменяемые объекты - это гораздо больше, чем это.

Если вы знаете, что объекты неизменяемы, их можно использовать для чтения среди множества потоков / клиентов, не беспокоясь о синхронизации, и легче понять, как работает программа.

осторожно - окончательный и неизменный - это совершенно разные понятия. Легко иметь конечный изменяемый объект - final относится к ссылке, изменяемость - к экземпляру объекта. последний человек olaf = новый человек (); olaf.setName («Олаф»);

Olaf Kock 26.09.2008 16:04

Точно: неизменяемые объекты - это одно, неизменяемые ссылки (т.е. final) - это совсем другое.

SCdF 27.09.2008 10:01

Но они тесно связаны, поскольку вы можете, объявив поле Person.name как final (и объявив класс final и ...), сделать объект Person окончательным. Однако это не так просто, как просто выполнить "final Person" ...

Sebastian Ganslandt 20.09.2009 22:50

Это также не имеет значения для локальных переменных (параметры являются локальными). Он применяется только к переменным класса, поэтому лишь частично решает вопрос.

Robin 13.09.2011 18:56
Ответ принят как подходящий

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

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

Поначалу кажется неловким видеть много ключевых слов final в вашем коде, но довольно скоро вы перестанете замечать само слово и просто подумаете, эта вещь никогда не изменится с этого момента (вы можете взять его у меня ;-)

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

Вместо использования ключевого слова final для параметров вы можете использовать инструмент статического анализа, такой как FindBugs, чтобы требовать, чтобы переменные параметра не переназначались. Таким образом, вы устраняете синтаксическую нагрузку и можете обеспечить ее соблюдение с помощью проверки FindBugs в инструменте непрерывной интеграции.

Timo Westkämper 16.05.2010 22:45

@Timo Это сработает, но у него есть обратная сторона: это нужно проверять после проверки, а не пока разработчик работает над кодом. Для final компилятор, очевидно, не позволит вам продолжить, если вы сделаете ошибку.

Mike 24.08.2010 22:00

@ Майк, согласен. Я люблю FindBugs и использую его неукоснительно, но когда есть функция языка и поддержка компилятора ... используйте ее! Да, я думаю, что final повсюду уродлив, и когда они наконец сделают несовместимую перезапись Java, я надеюсь, что по умолчанию все будет окончательно.

andersoj 21.10.2010 00:38

Eclipse имеет возможность добавлять final, когда это возможно (переменные, которые не изменяются) при сохранении.

Bert F 10.12.2010 18:37

+1 Обожаю final. В 98% случаев это не имеет значения, это незначительное неудобство в% 1 случаях, но 1% времени спасает меня от того, чтобы сделать что-то глупое или непреднамеренное, оно того стоит.

Bert F 10.12.2010 18:40

вот случай, когда использование final усложняет ваш код ... stackoverflow.com/questions/9350605/…

opensas 19.02.2012 23:41

@BertF Да, я всегда позволяю Eclipse добавлять модификаторы final повсюду, когда я "очищаю ..." свой код. Везде означает даже в блоках catch (), и, как сказано, вы их не заметите через некоторое время. Конечно, если бы я создал язык, final был бы по умолчанию, а var или modifiable было бы необязательным ключевым словом.

Maarten Bodewes 17.03.2012 17:30

@MaartenBodewes Забавно, теперь на JVM работает язык, где по умолчанию используется final: Котлин

Joschua 26.06.2016 01:09

@Joschua Поверьте мне, я с большим интересом слежу за Котлином. Он по-прежнему содержит целочисленные переполнения и тому подобное, но в остальном это кажется шагом в правильном направлении.

Maarten Bodewes 26.06.2016 01:47

"эта-вещь-никогда-никогда не изменится с этой точки" жаль, что она не работает таким образом с изменяемыми объектами.

Dogcat 08.07.2016 11:10

Особенно, когда вы сотрудничаете, это ооочень полезно! Часто, когда я не уверен, что делает переменная / поле, или если оно где-то видоизменилось, я просто вставляю перед ним final и позволяю компилятору разобраться в этом: P Если он компилируется, отлично! Оставьте его, чтобы его было легче прочитать следующему человеку. Если нет, то, по крайней мере, вы точно знаете все критические моменты, в которых он используется.

Daniel W. 21.08.2017 18:48

Final при использовании с переменными в Java обеспечивает замену константы в C++. Поэтому, когда для переменной используются final и static, она становится неизменной. В то же время очень довольны мигрировавшие программисты на C++ ;-)

При использовании со ссылочными переменными он не позволяет вам повторно ссылаться на объект, хотя объектом можно манипулировать.

Когда final используется с методом, он не позволяет переопределить метод подклассами.

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

Его следует использовать для переменных только тогда, когда вы чертовски уверены, что значение переменной никогда не будет / не должно изменяться. Также убедитесь, что вы следуете соглашению о кодировании, рекомендованному SUN. Например: final int COLOR_RED = 1; (Верхний регистр разделен подчеркиванием)

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

Что касается читабельности, следует отметить, что комментарии играют очень важную роль при использовании модификатора final.

Вероятно, это потому, что вы заявляете, что должны делать его ТОЛЬКО при XYZ. Другие считают, что лучше сделать ВСЕ окончательным, если в этом нет необходимости.

Outlaw Programmer 30.09.2008 22:46

Это вовсе не замена ключевому слову const в C++. -1.

tmj 02.06.2016 12:37

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

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

В опубликованной выше статье приводится такой пример:

public void doSomething(int i, int j) {
    final int n = i + j; // must be declared final

    Comparator comp = new Comparator() {
        public int compare(Object left, Object right) {
            return n; // return copy of a local variable
        }
    };
}

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

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

Что касается классов, то только для некоторых классов инфраструктуры я использовал final class.

IntelliJ IDEA предупреждает вас, если параметр функции записан внутри функции. Итак, я перестал использовать final для аргументов функции. Я также не вижу их внутри библиотеки времени выполнения Java.

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

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

Chris Vest 26.09.2008 13:32

Модификатор final, особенно для переменных, является средством заставить компилятор применять соглашение, которое в целом является разумным: убедитесь, что переменная (локальная или экземплярная) назначается ровно один раз (не больше и не меньше). Убедившись, что переменная определенно назначена перед ее использованием, вы можете избежать распространенных случаев NullPointerException:

final FileInputStream in;
if (test)
  in = new FileInputStream("foo.txt");
else
  System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned

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

 String msg = null;
 for(int i = 0; i < 10; i++) {
     msg = "We are at position " + i;
     System.out.println(msg);
 }
 msg = null;

Вам предлагается использовать это:

 for(int i = 0; i < 10; i++) {
     final String msg = "We are at position " + i;
     System.out.println(msg);
 }

Некоторые ссылки:

Короче говоря, вы можете использовать от final до сделать Java более выраженной.

Adam Gent 17.09.2013 21:31

На самом деле «Убедившись, что переменная определенно назначена перед ее использованием, вы можете избежать распространенных случаев исключения NullPointerException:» это неверно, 'final' здесь не имеет значения, компилятор знает и жалуется на переменную 'in', возможно в приведенном примере имеет значение NULL.

nyholku 29.01.2019 17:14

@nyholku Вы правы, в Java локальные переменные должны быть обязательно назначены перед использованием, также без final. Но для полей нужен финал. В несколько более сложном примере, где «in» - это переменная экземпляра класса, а if / else находится в конструкторе, вам нужен финал, чтобы сигнализировать о проблеме. Кроме того, также для локальных переменных есть некоторое значение в окончательном IMO, поскольку оно не позволяет неаккуратному программисту «исправить» ошибку компиляции о том, что «in», возможно, не назначено, добавив «= null» к его объявлению. Другими словами, по моему опыту, конечные переменные сокращают использование null.

Bruno De Fraine 01.02.2019 16:18

Я все время использую final для атрибутов объектов.

Ключевое слово final имеет семантику видимости при использовании в атрибутах объекта. По сути, установка значения атрибута final объекта происходит до того, как конструктор вернется. Это означает, что до тех пор, пока вы не позволяете ссылке this ускользать из конструктора и используете final для атрибутов все, ваш объект (в соответствии с семантикой Java 5) гарантированно будет правильно сконструирован, а поскольку он также является неизменяемым, он может быть безопасно опубликовано в других темах.

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

Иногда я также делаю методы финальными, но не так часто. Я редко заканчиваю уроки. Обычно я делаю это потому, что мне это не нужно. Обычно я не особо использую наследование. Вместо этого я предпочитаю использовать интерфейсы и композицию объектов - это также поддается дизайну, который, как мне кажется, часто легче проверить. Когда вы кодируете интерфейсы вместо конкретных классов, тогда вы не можете использовать необходимость для использования наследования, когда вы тестируете, как есть, с такими фреймворками, как jMock, гораздо проще создавать макетные объекты с интерфейсами, чем с конкретными классами.

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

Для работы мне приходится читать много кода. Отсутствие final в переменных экземпляра - одна из главных вещей, которые меня раздражают и излишне затрудняют понимание кода. На мой взгляд, final по локальным переменным вызывает больше беспорядка, чем ясности. Язык должен был быть разработан так, чтобы сделать это по умолчанию, но мы должны жить с ошибкой. Иногда это полезно, особенно с циклами и определенным присваиванием с деревом if-else, но в основном это указывает на то, что ваш метод слишком сложен.

Почему бы не использовать инструмент, уменьшающий беспорядок?

Pacerier 17.05.2020 16:34

@Pacerier Как редактор, искажающий код?

Tom Hawtin - tackline 18.05.2020 14:24

Зацикливаться на:

  • Конечные поля - пометка полей как конечных приводит к тому, что они будут установлены к концу построения, что делает ссылку на поле неизменной. Это обеспечивает безопасную публикацию полей и позволяет избежать необходимости синхронизации при последующих чтениях. (Обратите внимание, что для ссылки на объект неизменной является только ссылка на поле - вещи, на которые ссылается объектная ссылка, могут по-прежнему изменяться, и это влияет на неизменяемость.)
  • Конечные статические поля. Хотя сейчас я использую перечисления во многих случаях, когда я использовал статические конечные поля.

Подумайте, но используйте разумно:

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

Игнорируйте, если не чувствуете себя анальным:

  • Параметры метода и локальные переменные - Я РЕДКО делаю это в основном потому, что я ленив и считаю, что это загромождает код. Я полностью признаю, что маркировка параметров и локальных переменных, которые я не собираюсь изменять, «правильнее». Хотелось бы, чтобы это было по умолчанию. Но это не так, и я считаю, что код сложнее понять из-за финала повсюду. Если я нахожусь в чужом коде, я не собираюсь их вытаскивать, но если я пишу новый код, я не буду их вставлять. Одно исключение - это случай, когда вам нужно пометить что-то окончательное, чтобы вы могли получить доступ это изнутри анонимного внутреннего класса.

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

nyxz 07.11.2012 13:50

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

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

Это также не имеет отношения к неизменяемости, поскольку лучший индикатор неизменности чего-либо - это то, что оно задокументировано как таковое и / или не имеет методов, которые могут изменить объект (это, наряду с окончательным окончанием класса, является единственным способом гарантировать, что он неизменен).

Но это только мое мнение :-)

Я настроил Eclipse, чтобы добавить final для всех полей и атрибутов, которые не изменяются. Это отлично работает с использованием Eclipse «save actions», который добавляет эти последние модификаторы (среди прочего) при сохранении файла.

Настоятельно рекомендуется.

Ознакомьтесь с мой пост в блоге из Eclipse Save Actions.

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

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

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

Final всегда следует использовать для констант. Это даже полезно для недолговечных переменных (в рамках одного метода), когда правила определения переменной сложны.

Например:

final int foo;
if (a)
    foo = 1;
else if (b)
    foo = 2;
else if (c)
    foo = 3;
if (d)        // Compile error:  forgot the 'else'
    foo = 4;
else
    foo = -1;

Маркировка класса final также может привести к привязке некоторых методов во время компиляции, а не во время выполнения. Рассмотрим "v2.foo ()" ниже - компилятор знает, что B не может иметь подкласс, поэтому foo () не может быть переопределен, поэтому реализация для вызова известна во время компиляции. Если класс B НЕ помечен как окончательный, то возможно, что фактический тип v2 - это некоторый класс, который расширяет B и переопределяет foo ().

class A {
    void foo() {
        //do something
    }
}
final class B extends A {
    void foo() {
    }
}
class Test {
    public void t(A v1, B v2) {
        v1.foo();
        v2.foo();
    }
}

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

И этот пост - яркое тому доказательство.

inigoD 03.03.2016 17:37

final можно изменить через setter ().

logbasex 11.09.2020 10:58

Я довольно категоричен в отношении объявления всех возможных переменных final. Сюда входят параметры метода, локальные переменные и, в редких случаях, поля объекта значений. У меня есть три основные причины для объявления финальных переменных повсюду:

  1. Объявление намерения: объявляя конечную переменную, я заявляю, что эта переменная предназначена для записи только один раз. Это тонкий намек для других разработчиков и большой намек для компилятора.
  2. Обеспечение одноразовых переменных: я верю в идею, что каждая переменная должна иметь только одно предназначение в жизни. Назначая каждой переменной только одно предназначение, вы сокращаете время, необходимое для выяснения назначения этой конкретной переменной во время отладки.
  3. Допускает оптимизацию: я знаю, что в компиляторе использовались уловки для повышения производительности, которые основывались именно на неизменности ссылки на переменную. Мне нравится думать, что некоторые из этих старых уловок производительности (или новых) будут использованы компилятором.

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

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

Steve Kuo 22.04.2014 01:40

переменная: = латинский: varius> разный> изменяемый

dieter 02.12.2014 17:56

Даже для локальных переменных знание того, что он объявлен как final, означает, что мне не нужно беспокоиться о том, что ссылка будет изменена позже. Это означает, что при отладке, и я вижу эту переменную позже, я уверен, что она ссылается на один и тот же объект. Это на одну вещь меньше, о чем мне нужно беспокоиться при поиске ошибки. Бонус в том, что если 99% переменных объявлены окончательными, то несколько переменных, которые действительно являются переменными, выделяются лучше. Кроме того, финал позволяет компилятору найти еще несколько возможных глупых ошибок, которые в противном случае могли бы остаться незамеченными.

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

Тот факт, что Eclipse окрашивает конечный красный цвет, упрощает обнаружение объявлений переменных в коде, что, как мне кажется, в большинстве случаев улучшает читаемость.

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

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

Последняя переменная - это просто хороший способ пометить значения.

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

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

Я уже некоторое время кодирую и использую final, когда могу. Сделав это некоторое время (для переменных, параметров метода и атрибутов класса), я могу сказать, что 90% (или более) моих переменных фактически являются окончательными. Я думаю, что преимущество НЕ изменять переменные, когда вы этого не хотите (я видел это раньше, и иногда это больно), окупается за дополнительный набор текста и дополнительные «финальные» ключевые слова в вашем коде.

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

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

Я также использую Collections.unmodifiable ... для создания неизменяемых списков, когда мне нужно.

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

Если мы признаем многие преимущества «final», как указано во многих замечательных публикациях здесь, и при этом признаем, что это требует больше ввода и места, я бы сказал, что Java должна была сделать переменные «final» по умолчанию и потребовать, чтобы все было помечено « mutable ", если кодировщик этого хочет.

Странно тогда называть это переменной, не так ли?

Alan 31.10.2014 20:14

Есть тысячи английских слов на выбор.

RAY 07.11.2014 09:01

Это потрясающе. Против final нет аргументов, кроме «слишком долго писать», «делает код более неуклюжим». В пользу final есть несколько аргументов. И мы можем автоматически добавлять его при сохранении, если вы не хотите вводить его вручную.

Dmitriy Popov 16.04.2020 15:08

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

Как только раздражение выходит за рамки разумного, переключитесь на Scala, где аргументы по умолчанию являются окончательными.

Или вы всегда можете использовать инструменты стилизации кода, которые сделают это автоматически. Во всех IDE они реализованы или в виде плагинов.

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