2010-11-12 4 views
53

Какая разница между заключительным кодом между приведенным ниже кодом. Есть ли преимущество в объявлении аргументов как окончательных.Выполнение аргументов метода java как окончательного

public String changeTimezone(Timestamp stamp, Timezone fTz, Timezone toTz){ 
    return .... 
} 

public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
     final Timezone toTz){ 
    return .... 
} 
+3

Существуют анализаторы кода, которые предупреждают, если параметр повторно используется или переназначен. (То же самое для локальных переменных) IMHO. Это лучший способ поймать такие параметры, если вы обнаружите, что их изменение нежелательно. –

+0

Возможный дубликат [Почему я должен использовать ключевое слово «final» для параметра метода в Java?] (Https://stackoverflow.com/questions/500508/why-should-i-use-the-keyword-final-on -a-method-parameter-in-java) –

ответ

75

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

Это избавит вас от объявления другого местного окончательных переменного в теле метода:

void m(final int param) { 
     new Thread(new Runnable() { 
      public void run() { 
       System.err.println(param); 
      } 
     }).start(); 
    } 
+18

+1: Это важный прецедент, и единственный раз, когда вы * нуждаетесь в нем. (В остальное время это просто вопрос того, что удобно для помощи программисту.) –

+3

Могу ли я спросить об этом? – KodeWarrior

+11

Нет необходимости в Java 8. –

10

Это не имеет большого значения. Это просто означает, что вы не можете написать:

stamp = null; 
fTz = new ...; 

но вы можете написать:

stamp.setXXX(...); 
fTz.setXXX(...); 

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

15

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

Должен признаться, что я редко помню, чтобы использовать 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; 
} 
0

Его просто конструкция на Java, чтобы помочь вам определить контракт и придерживаться его. Аналогичная дискуссия здесь: http://c2.com/cgi/wiki?JavaFinalConsideredEvil

BTW - (как говорит twiki), обозначение args как final обычно является избыточным, если вы следуете хорошим принципам программирования и выполняете hass, переназначив/переопределите ссылку на входящие аргументы.

В худшем случае, если вы переопределите ссылку args, это не повлияет на фактическое значение, переданное функции, поскольку передано только эта ссылка.

2

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

+1

Мне нужно что-то добавить: если параметры примитивны, я не вижу различий. Кроме того, если параметрами являются Collections (список объектов ...), добавление final не может предотвратить их изменение. – Sam003

+1

Неизменность всегда является желательной чертой. Java не имеет его из коробки. Создание переменных окончательно, по крайней мере, обеспечивает целостность ссылок. – Sid

+0

Согласен. Но если мы действительно хотим достичь неизменности объектов, мы могли бы попробовать сделать глубокий клон. – Sam003

19

Выписка из The final word on the final keyword

Окончательные параметры

Следующий пример объявляет окончательные параметры:

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... 
} 

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

Обратите внимание, что окончательные параметры не считаются частью методы подписи, и игнорируются компилятором при разрешении вызовов методов. Параметры могут быть объявлены окончательными (или нет) без влияния на способ переопределения метода .

+8

Возможно, лучше использовать для этого примера объекты, а не примитивы, поскольку примитивные изменения всегда будут видны только внутри метода. А в случае объектов вы все равно можете их изменить. Вы просто не можете указать на новый объект. Фактически, теперь я думаю об этом, окончательный ничего не меняет по сравнению с оставлением его, кроме сохранения объявления переменной с AIC и наличия компилятора указывает на случайные модификации параметров, которые вы не хотели изменять по какой-либо причине , –

1

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

0

Я говорю о маркировке переменных и полей final в целом - не относится только к аргументам метода. (Маркеры/классы окончательные совсем другое).

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

-3

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

Предположим, что у нас есть метод

method1() {

Дата DateOfBirth = новая дата ("1/1/2009");

способ2 (датаOfBirth);

способ3 (датаOfBirth); }

общественного mehod2 (Дата DateOfBirth) {
....
....
....
}

общественного mehod2 (Дата DateOfBirth) {
....
....
....
}

В приведенном выше случае, если «dateOfBirth» присвоено новое значение в методе2, это приведет к неправильному выводу метода method3. Поскольку значение, которое передается методу3, не является тем, что было перед передачей методу2. Поэтому, чтобы избежать этого ключевого слова final, используется для параметров.

И это также одна из лучших практик Java-кодирования.

+5

Это не совсем так. Даже если аргумент dateOfBirth изменен на другое значение в методе2(), это не повлияет на метод2(), поскольку Java передает значение, а не по ссылке. – Flo

Смежные вопросы