Создание аргументов метода Java в качестве окончательного - PullRequest
74 голосов
/ 12 ноября 2010

Какая разница, что 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 ....
}

Ответы [ 9 ]

104 голосов
/ 12 ноября 2010

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

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

 void m(final int param) {
        new Thread(new Runnable() {
            public void run() {
                System.err.println(param);
            }
        }).start();
    }
36 голосов
/ 12 ноября 2010

Выписка из Последнее слово в последнем ключевом слове

Конечные параметры

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

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 используется здесь для обеспечения двух индексы I и J не будет случайно сброс по методу. Это удобный способ защитить от коварной ошибки что ошибочно меняет значение ваши параметры. Вообще говоря, короткие методы - лучший способ защитить от этого класса ошибок, но конечные параметры могут быть полезны дополнение к вашему стилю кодирования.

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

22 голосов
/ 12 ноября 2010

Последнее не позволяет вам присвоить новое значение переменной, и это может быть полезно при обнаружении опечаток.Стилистически вы можете оставить полученные параметры без изменений и назначить их только локальным переменным, поэтому 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;
}
13 голосов
/ 12 ноября 2010

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

stamp = null;
fTz = new ...;

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

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

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

3 голосов
/ 12 ноября 2010

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

2 голосов
/ 12 ноября 2010

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

0 голосов
/ 12 ноября 2010

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

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

method1 () {

Date dateOfBirth = new Date ("1/1/ 2009 ");

method2 (dateOfBirth);

method3 (dateOfBirth);}

общедоступный метод2 (Дата dateOfBirth) {
....
....
....
}

общедоступный метод2 (Дата dateOfBirth) {
....
....
....
}

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

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

0 голосов
/ 12 ноября 2010

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

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

0 голосов
/ 12 ноября 2010

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

Кстати - (как говорит твики), маркировка аргументов как окончательных обычно избыточна, если вы следуете хорошим принципам программирования, и если все сделано, переназначьте / переопределите ссылку на входящий аргумент.

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

...