Как уже упоминалось, final
используется с методом Java, чтобы отметить, что метод не может быть переопределен (для области объекта) или скрыт (для статического). Это позволяет исходному разработчику создавать функциональные возможности, которые не могут быть изменены подклассами, и это вся гарантия, которую он предоставляет.
Это означает, что если метод полагается на другие настраиваемые компоненты, такие как закрытые поля / методы, функциональность последнего метода все еще может быть настраиваемой. Это хорошо, поскольку (с полиморфизмом) позволяет частичную настройку.
Есть ряд причин, по которым что-то нельзя настраивать, в том числе:
Производительность - некоторые компиляторы могут анализировать и оптимизировать работу, особенно без побочных эффектов.
Получите инкапсулированные данные - посмотрите на неизменяемые объекты, где их атрибуты установлены во время построения и никогда не должны изменяться. Или рассчитанное значение, полученное на основе этих атрибутов. Хороший пример - String
класс Java .
Надежность и Договор - Объекты состоят из примитивов ( int
, char
, double
, и т.д.) и / или других объектов. Не все операции, применимые к этим компонентам, должны быть применимы или даже логичны, когда они используются в более крупном объекте. Для этого final
можно использовать методы с модификатором. Класс Counter - хороший пример.
public class Counter {
private int counter = 0;
public final int count() {
return counter++;
}
public final int reset() {
return (counter = 0);
}
}
Если public final int count()
метода нет final
, мы можем сделать что-то вроде этого:
Counter c = new Counter() {
public int count() {
super.count();
return super.count();
}
}
c.count();
Или что-то вроде этого:
Counter c = new Counter() {
public int count() {
int lastCount = 0;
for (int i = super.count(); --i >= 0; ) {
lastCount = super.count();
}
return lastCount;
}
}
c.count();
Прежде всего, вы можете отмечать не абстрактные классы,
final
а также поля и методы. Таким образом, нельзя разделить весь класс на подклассы. Итак, поведение класса будет исправлено.Я согласен с тем, что методы маркировки
final
не гарантируют, что их поведение будет таким же в подклассах, если эти методы вызывают неокончательные методы. Если поведение действительно необходимо исправить, это должно быть достигнуто с помощью условностей и тщательного проектирования. И не забудьте указать это в javadoc! (Java-документация)И последнее, но не менее важное:
final
ключевое слово играет очень важную роль в модели памяти Java (JMM). JMM гарантирует, что для обеспечения видимостиfinal
полей вам не нужна надлежащая синхронизация. Например:class A implements Runnable { final String caption = "Some caption"; void run() { // no need to synchronize here to see proper value of final field.. System.out.println(caption); } }
источник
String
, а в пользовательских классах). Но то, что вы сказали о «final не гарантирует поведения», в точности мою. Согласен, важны документы и дизайн.final
не гарантирует видимости изменений, внесенных в составные объекты, такие какMap
.Я не уверен, что вы можете делать какие-либо утверждения об использовании "final" и о том, как это влияет на общий контракт на разработку программного обеспечения. Вам гарантируется, что ни один разработчик не сможет отменить этот метод и таким образом аннулировать свой контракт. Но с другой стороны, последний метод может полагаться на переменные класса или экземпляра, значения которых устанавливаются подклассами, и может вызывать другие методы класса, которые переопределяются. Так что final - это в лучшем случае очень слабая гарантия.
источник
const
. Как вchar const * const = "Hello"
илиchar const * const addName(char const * const name) const
...Нет, это не без влияния автора класса. Вы не можете переопределить его в производном классе, поэтому он будет делать то, что задумал автор базового класса.
http://download.oracle.com/javase/tutorial/java/IandI/final.html
Стоит отметить ту часть, где предполагается, что методы должны быть вызваны из конструкторов
final
.источник