Не конечные методы в конечном классе
Мой вопрос довольно прост:
Компилятор рассматривает все методы в конечном классе как окончательные сами? Влияет ли добавление ключевого слова final
в методы в конечном классе?
Я понял, что у окончательных методов есть больше шансов на вступление, и именно поэтому я спрашиваю.
Спасибо заранее.
Ответы
Ответ 1
Вы правы, все методы в конечном классе неявно окончательно.
Смотрите здесь:
"Обратите внимание, что вы также можете объявить окончательный класс класса. объявленный окончательный не может быть подклассом. Это особенно полезно для например, при создании неизменяемого класса, такого как класс String."
И здесь:
Все методы в конечном классе неявно окончательно.
Это также может вас заинтересовать: Рекомендации по эффективности ключевого слова Java final
Ответ 2
Компилятор рассматривает все методы в конечном классе как окончательные?
По сути, да, это так. Метод в классе final
нельзя переопределить. Добавление (или удаление) ключевого слова final
к методу не имеет никакого отношения к этому правилу.
Влияет ли добавление ключевого слова final в методы в конечном классе?
На практике это имеет минимальный эффект. Он не влияет на правила переопределения (см. Выше) и не влияет на вложение (см. Ниже).
Во время выполнения можно указать, был ли метод объявлен с ключевым словом final
... с использованием отражения, чтобы посмотреть флаги метода. Таким образом, это имеет некоторый эффект, хотя и эффект, который не имеет значения для 99,99% программ.
Я понял, что у окончательных методов есть больше шансов на вступление, и именно поэтому я спрашиваю.
Это понимание неверно. Компилятор JIT в современных JVM отслеживает, какие методы не переопределяются в классах, загружаемых приложением. Он использует эту информацию, а статические типы определяют, требует ли конкретный вызов диспетчер виртуального класса или нет. Если нет, то встраивание возможно и будет использоваться в зависимости от того, насколько велик тело метода. По сути, компилятор JIT игнорирует наличие/отсутствие final
и использует более точный метод для обнаружения вызовов методов, где допускается встраивание метода.
(На самом деле это сложнее, чем это.Приложение может динамически загружать подклассы, которые приводят к неправильному анализу метода компилятора JIT. Если это произойдет, JVM должен аннулировать любые обработанные методы и заставить их перекомпилировать.)
В нижней строке:
-
Нет никакого преимущества в производительности при добавлении методов final
в классы final
.
-
В final
может быть преимущество производительности в классах final
, но только если вы используете старую Sun JVM или какую-то другую Java/Java-платформу с низким качеством JIT-компилятор.
Если вы заботитесь о производительности, лучше использовать современную/высокопроизводительную Java-платформу с достойным компилятором JIT, чем загрязнять свою кодовую базу ключевыми словами final
, которые могут вызвать проблемы в будущее.
Вы написали в комментарии:
@RussellZahniser Я читал по-разному во многих местах.
Интернет полон старой информации, большая часть которой устарела... или никогда не была правильной в первую очередь.
Ответ 3
Может быть, компилятор рассматривает их как final.
Следующие отпечатки "false":
final class FinalClass {
public void testMethod() {}
}
Method method = FinalClass.class.getDeclaredMethod("testMethod");
int m = method.getModifiers();
System.out.println(Modifier.isFinal(m));