JavaRush/Курсы/Java Multithreading/final и другие ключевые слова java

final и другие ключевые слова java

Открыта
final и другие ключевые слова java - 1

— Привет, Амиго!

— Привет, Билаабо!

— Я расскажу тебе сегодня про несколько ключевых слов в Java. Но начну с самого интересного – ключевого слова final. Если перевести его с английского, то получится что-то вроде финальный или окончательный.

Ключевое слово final можно добавлять при объявлении переменной, метода и класса.

— А зачем нужен этот final?

— Все довольно просто. Если мы пометили переменную словом final, то она становится неизменной:

final int i = 5;
i++; //ошибка компиляции – нельзя менять значение переменной i

— Ясно.

— Если мы пометили метод словом final, то этот метод запрещено переопределять в классах-наследниках:

class Cat
{
 public final String getName()
 {
  return "cat";
 }
}

class Tiger extends Cat
{
 public String getName() //ошибка компиляции – нельзя переопределять метод getName()
 {
  return "tiger";
 }
}

— Ясно. А зачем может понадобиться запрещать переопределение метода?

— Например, программист написал в этом методе много важного кода и хочет, чтобы все наследники его класса гарантированно имели заданное поведение.

И наконец – третье.

Если мы пометим словом final класс, то таким образом мы запретим наследоваться от него.

public final class Cat
{
 public String getName()
 {
  return "cat";
 }
}

class Tiger extends Cat //ошибка компиляции – нельзя наследоваться от класса Cat
{
 public String getName()
 {
  return "tiger";
 }
}

— А зачем запрещать наследование классов?

— Ты должен понять, что запрет наследования идет не из вредности, а ради безопасности и целостности кода. Если наследование класса не запрещено, то подразумевается, что оно разрешено. И код проектировщика класса будет нормально работать и с объектами его класса и с объектами класса-наследника.

А вот если разработчик видит, что даже при небольших изменениях в его классе, все перестанет работать, как задумано, тогда ему лучше запретить наследование.

— Класс String, например, объявлен как final, как и все примитивные типы: Integer, Boolean, Double, Character,…

— Ага, понимаю. Класс String сделан immutable и если бы вдруг появились изменяемые строки, то много чего перестало бы работать.

— Ну, почти. Скажем так, все работало бы почти по-старому, но иногда возникали бы ошибки, которые было бы очень сложно найти и понять. Поэтому, в некоторых случаях наследование классов или методов не грех и запретить – меньше потом ошибок вылавливать.

— А где еще можно писать final?

— final можно писать перед переменными-аргументами функции и перед переменными в методе. Вот пример:

public void setName(final String name)
{
 final String displayName = "Mr."+name;
  …
 this.name = displayName;
}

— А какой в этом смысл?

— Ну, смыслов – два. Во-первых, мы объявляем переменную final – если хотим сообщить другим разработчикам, что это значение – определенная константа, а не просто переменная.

Например, мы хотим рассчитать НДС от цены:

public int getPriceNDS()
{
 final int NDS = 20;
 return this.price * NDS / 200;
}

И во-вторых, если мы будем писать локальные или анонимные внутренние классы, то такие переменные нам понадобятся. Я расскажу о таких классах в ближайшее время. Но не сегодня.

— Ок, пока вроде ничего сложного.

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

— Как раз хотел уточнить этот момент. А нет способа сделать объект неизменным?

— Нет, только если ты напишешь immutable класс.

Обрати внимание на такой момент — т.к. значение переменной менять нельзя, то ей сразу нужно присвоить начальное значение:

Этот код скомпилируется Этот код не скомпилируется
class Home
{
 private final int width = 200;
 private final int height = 100;

 public Home()
 {
 }
}
class Home
{
 private final int width; private final int height;

 public Home()
 {
 }
}

Но, вместе с тем, Java разрешает перенести инициализацию final-переменных класса в конструктор.

Этот код скомпилируется Этот код не скомпилируется
class Home
{
 private final int width = 200;
 private final int height;

 public Home()
 {
  height = 100;
 }
}
class Home
{
 private final int width;
 private final int height;

 public Home()
 {
  height = 100;
 }
}

Более того, в разных конструкторах final-переменные можно инициализировать разными значениями. Это очень удобно:

Этот код скомпилируется
class Home
{
 private final int width;
 private final int height;

 public Home()
 {
  height = 100; width = 200;
 }

 public Home(int width)
 {
 this.height = 300; this.width = width;
 }

 public Home(int width, int height)
 {
 this.height = height; this.width = width;
 }
}

— Действительно интересная тема, и абсолютно все понятно, спасибо, Билаабо!

Комментарии (64)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Zim4ik
Уровень 1
8 июля 2025, 13:40
Класс String, например, объявлен как final, как и все примитивные типы: Integer, Boolean, Double, Character Примитивные типы (например, int, double, boolean) — это не классы вообще. Они — встроенные типы языка Java, и не имеют модификаторов вроде final. Но для них существуют классы-обёртки, и вот они-то — final.
Anemon
Уровень 13
Expert
25 ноября 2024, 21:14
Всегда было интересно, в чем именно различие.
SomeBody098веник в бане
20 июля 2024, 17:24
познавательно )
Максим Li Backend Developer
19 мая 2024, 20:48
19.05.2024
Long_byte
Уровень 60
13 мая 2024, 18:14
почему я всегда читаю Билаабо как Билбао
Anonymous #3390940
Уровень 38
13 марта 2024, 15:14
🦝
Алексей
Уровень 40
Expert
10 января 2024, 15:52
Хорошая леция все по делу
Lo
Уровень 35
Expert
23 ноября 2023, 13:58
В последнем примере в конструкторе поменяли расстановку в аргументах конструктора, а разве так можно делать? Вроде говорили,что как в параметрах так и инициализируем по порядку. Или это уже не важно стало в новой версии ? лекция то вроде не новая...
Rolik
Уровень 41
11 апреля 2023, 17:49
Не раскрыта разница между константами и final переменными. Имя константы в верхнем регистре - общепринятая условность, но не обязательное правило.
Виктор
Уровень 1
5 августа 2022, 12:05
Какой-то странный расчёт НДС, не говоря уже о том, что константой его назвать никак нельзя.
Lafaed
Уровень 36
5 марта 2023, 20:48
Это абстракция абстрагированная от реальности, призванная лишь показать пример взаимодействия и работу модификатора. Как красиво завернул =)