Я читал о последних методах сегодня. И кажется, что объявление финала класса - это всего лишь сокращение для объявления всех методов финальными.
Преимущество объявления метода final состоит в том, что он позволяет компилятору избегать использования поиска в виртуальной таблице при отправке метода, то есть он точно знает, в каком классе находится метод.
В Java методы по умолчанию являются виртуальными, тогда как в C ++ верно обратное. Единственные методы, которые не являются виртуальными в Java, - это статические методы и конечные методы.
Выигрыш в производительности от явного объявления метода final является спорным. Хороший JIT-компилятор сможет анализировать код и выполнять любые оптимизации, которые он сочтет полезными. Если класс A в настоящее время не имеет загруженных подклассов, то JIT-компилятор может решить оптимизировать любые пути кода, которые вызывают методы экземпляра A, если они вызываются часто. Это включает в себя избавление от поиска в vtable или даже вставку вызова метода.
например. следующий путь кода является хорошим кандидатом для оптимизации, если метод выполняется быстро.
public void run(A instance) {
while (true) {
instance.method();
}
}
Если впоследствии загружается подкласс A, который переопределяет метод, то JIT-компилятор может лишить законной силы любые оптимизации, сделанные в отношении вызова метода.
По сути, хороший JIT может дать все преимущества объявления чего-то окончательного, без необходимости объявления чего-либо окончательного. И поскольку нам не нужно объявлять что-либо окончательное, мы можем разработать полностью объектно-ориентированный подход, не беспокоясь о том, является ли определенный класс или метод конечным. Следовательно, final должен использоваться только для целей документирования. Единственное исключение - это поля класса, поскольку он помечает любые вычисления с этими полями как кандидатов на запоминание - то есть кэширует результат и использует кэшированный результат, а не выполняет вычисление снова.