Какая разница final
между приведенным ниже кодом. Есть ли преимущество в объявлении аргументов как final
.
public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){
return ....
}
public String changeTimezone(final Timestamp stamp, final Timezone fTz,
final Timezone toTz){
return ....
}
Ответы:
Поскольку формальный параметр метода является локальной переменной, вы можете получить к ним доступ из внутренних анонимных классов, только если они объявлены как final.
Это избавляет вас от объявления другой локальной конечной переменной в теле метода:
void m(final int param) { new Thread(new Runnable() { public void run() { System.err.println(param); } }).start(); }
источник
Выдержка из последнего слова о последнем ключевом слове
public void doSomething(final int i, final int j) { // cannot change the value of i or j here... // any change would be visible only inside the method... }
источник
Последний не позволяет вам присвоить переменной новое значение, и это может быть полезно для выявления опечаток. Стилистически вы можете оставить полученные параметры неизменными и назначить их только локальным переменным, поэтому final поможет обеспечить соблюдение этого стиля.
Должен признаться, я редко вспоминаю об использовании final для параметров, может, стоит.
public int example(final int basicRate){ int discountRate; discountRate = basicRate - 10; // ... lots of code here if ( isGoldCustomer ) { basicRate--; // typo, we intended to say discountRate--, final catches this } // ... more code here return discountRate; }
источник
Это не имеет большого значения. Это просто означает, что вы не можете писать:
stamp = null; fTz = new ...;
но вы все равно можете написать:
В основном это подсказка программисту по обслуживанию, который следует за вами, что вы не собираетесь назначать новое значение параметру где-то в середине вашего метода, где это неочевидно и поэтому может вызвать путаницу.
источник
Ключевое слово final при использовании для параметров / переменных в Java отмечает ссылку как окончательную. В случае передачи объекта другому методу система создает копию ссылочной переменной и передает ее методу. Помечая новые ссылки как окончательные, вы защищаете их от переназначения. Иногда это считается хорошей практикой кодирования.
источник
Для тела этого метода
final
ключевое слово предотвратит случайное переназначение ссылок аргументов, что приведет к ошибке компиляции в этих случаях (большинство IDE сразу же пожалуются). Некоторые могут возразить, что использованиеfinal
по возможности в целом ускорит процесс, но это не относится к недавним JVM.источник
Перечислены два преимущества, которые я вижу:
1 Пометка аргумента метода как окончательного предотвращает переназначение аргумента внутри метода
Из твоего примера
public String changeTimezone(final Timestamp stamp, final Timezone fTz, final Timezone toTz){ // THIS WILL CAUSE COMPILATION ERROR as fTz is marked as final argument fTz = Calendar.getInstance().getTimeZone(); return .. }
В сложном методе отметка аргументов как final поможет в случайной интерпретации этих аргументов как локальных переменных метода, а переназначение в качестве компилятора пометит эти случаи, как показано в примере.
2 Передача аргумента анонимному внутреннему классу
Поскольку формальный параметр метода является локальной переменной, вы можете получить к ним доступ из внутренних анонимных классов, только если они объявлены как final.
источник
- В прошлом (до Java 8 :-))
Использование Explit ключевого слова final повлияло на доступность переменной метода для внутренних анонимных классов.
- В современном (Java 8+) языке нет необходимости в таком использовании:
В Java были введены «фактически конечные» переменные. Локальные переменные и параметры метода считаются окончательными, если код не предполагает изменения значения переменной. Поэтому, если вы видите такое ключевое слово в Java8 +, вы можете считать, что оно не нужно. Введение «фактически окончательного» заставляет нас печатать меньше кода при использовании лямбда-выражений.
источник
Это просто конструкция в Java, которая поможет вам определить контракт и придерживаться его. Аналогичное обсуждение здесь: http://c2.com/cgi/wiki?JavaFinalConsideredEvil
BTW - (как говорит твики), маркировка args как final обычно избыточна, если вы следуете хорошим принципам программирования и не можете переназначить / переопределить ссылку на входящий аргумент.
В худшем случае, если вы переопределите ссылку args, это не повлияет на фактическое значение, передаваемое функции, поскольку была передана только ссылка.
источник
Я говорю об окончательной маркировке переменных и полей в целом - не только для аргументов метода. (Пометить методы / классы final - совсем другое дело).
Это услуга читателям / будущим сопровождающим вашего кода. Вместе с разумным именем переменной для читателя вашего кода полезно и обнадеживает возможность увидеть / понять, что представляют собой рассматриваемые переменные, и успокаивает читателя, что всякий раз, когда вы видите переменную в той же области видимости, значение остается то же самое, поэтому ему не нужно чесать голову, чтобы всегда понимать, что означает переменная в каждом контексте. Мы видели слишком много случаев злоупотребления «повторным использованием» переменных, что затрудняет понимание даже короткого фрагмента кода.
источник
Ключевое слово final не дает вам присвоить параметру новое значение. Я хотел бы пояснить это на простом примере
Предположим, у нас есть метод
В приведенном выше случае, если "dateOfBirth" присваивается новое значение в method2, это приведет к неправильному выводу из method3. Поскольку значение, которое передается в method3, не то, что было перед передачей в method2. Поэтому, чтобы избежать этого, последнее ключевое слово используется для параметров.
И это тоже одна из лучших практик программирования на Java.
источник