Ключевое слово final в параметрах метода

Я часто сталкиваюсь с методами, которые выглядят следующим образом:

public void foo(final String a, final int[] b, final Object1 c){
}

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

Ответ 1

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

Ответ 2

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

public FileFilter createFileExtensionFilter(final String extension) {
    FileFilter fileFilter = new FileFilter() {
        public boolean accept(File pathname) {
            return pathname.getName().endsWith(extension);
        }
    };

    // What would happen when it allowed to change extension here?
    // extension = "foo";

    return fileFilter;
}

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

Ответ 3

Java - это только пропускная способность. (или лучше - передать-ссылку-значение)

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

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

Ответ 4

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

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

Ответ 5

Рассмотрим эту реализацию foo():

public void foo(final String a) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.print(a);
        }
    }); 
}

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

Ответ 6

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

class Bike11 {  
    int cube(final int n) {  
        n=n+2;//can't be changed as n is final  
        n*n*n;  
     }  
    public static void main(String args[]) {  
        Bike11 b=new Bike11();  
        b.cube(5);  
    }  
}   

Вывод: ошибка времени компиляции

Для получения более подробной информации, пожалуйста, посетите мой блог: http://javabyroopam.blogspot.com

Ответ 7

final означает, что вы не можете изменить значение этой переменной после ее назначения.

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

Ответ 8

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

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

Но даже если вы переадресовываете параметр в методе, вызывающий не замечает этого, потому что java все передает параметр по значению. После последовательности

  a = someObject();
  process(a);

поля a могут быть изменены, но a все еще тот же объект, что и раньше. В языках с перекрестными ссылками это может быть неверно.

Ответ 9

@stuXnet, я мог бы сделать абсолютно противоположный аргумент. Если вы передадите объект функции, и вы измените свойства переданного объекта, то вызывающая функция увидит измененное значение в своей переменной. Это подразумевает пропуск по системе отсчета, а не пропуск по значению.

В чем сбивает с толку определение pass by value или pass by reference в системе, где использование указателей полностью скрыто для конечного пользователя.

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

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

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

Ответ 10

Конечное ключевое слово в параметре ввода метода не требуется. Java создает копию ссылки на объект, поэтому окончание на нем не делает объект окончательным, а просто ссылкой, что не имеет смысла

Ответ 11

Почти все было сказано о final параметрах метода в Java; но я хотел бы добавить маленькую простую вещь, что вы можете думать об этом final параметре метода как const параметры передачи по ссылке в C++, как показано ниже;

void someMethod(const int& param1)
{
  ...
}