Ключевое слово final
Ключевое слово final означает завершенный и может быть использовано для объявления переменных, методов и классов.
1. final переменные
Переменная может быть объявлено как final , что позволяет предотвратить изменение содержимого переменной, сделав ее, по существу, константой.
final переменная класса, объявленная как не static , должна инициализироваться при объявлении или в теле конструктора или блоке инициализации, иначе произойдет ошибка компиляции.
Кроме переменных, объявленными как final могут быть параметры метода и локальные переменные. final переменные, объявленные как static , должны быть проинициализированы при объявлении или в блоке инициализации, также объявленном как static . В противном случае опять получится ошибка компиляции.
Следующий пример показывает различные варианты объявления завершенных переменных:
public class FinalVariables < public static final int FILE_NEW = 1; private final String someString = "something"; public static void print(final double d) < // FILE_NEW = 2; final String str; str = "someString"; // str = ""; // d = 4; System.out.println("FILE_NEW = " + FILE_NEW); System.out.println("str = " + str); System.out.println("d header2">2. Константы Java Константы – это переменные, значение которых не меняется. Константами в Java принято называть public static final
переменные класса. Имена констант следует задавать только заглавными буквами, а слова в имени разделять знаком подчеркивания: MAX_WEIGHT
. Константы часто используются для борьбы с магическими (или волшебными) числами, то есть непонятно что означающими числами или строками. Например, следующий код содержит несколько раз повторяющееся магическое число 9.81:
public class PhysicsMagicNumber < public static double potentialEnergy(double mass, double height) < return mass * height * 9.81; >public static double getVelocity(double time) < return time * 9.81; >public static double getDistance(double time) < return 9.81 * time * time / 2; >>
Давайте перепишем код введя константу с именем ACCELERATION . Какие преимущества дает нам введение константы? Во-первых, имя константы уже объясняет значение этого числа, и, во-вторых, при желании изменить значение ACCELERATION , это можно сделать в одном месте. После рефакторинга:
public class Physics < public static final double ACCELERATION = 9.81; public static double potentialEnergy(double mass, double height) < return mass * height * ACCELERATION; >public static double getVelocity(double time) < return time * ACCELERATION; >public static double getDistance(double time) < return ACCELERATION * time * time / 2; >>
3. final методы
Чтобы запретить переопределение метода в классах наследниках, в начале его объявления следует указать ключевое слово final . Такие методы еще называют завершенными.
Нет смысла объявлять метод private final так как private метод не виден в наследниках, соответственно не может быть переопределен.
Также конструктор не может быть объявлен как final .
Класс O содержит завершенный метод, который не может быть переопределен в классе наследнике P . При попытке возникнет ошибка компиляции:
4. final классы
Для предотвращения наследование класса в начале объявления класса следует указать ключевое слово final . Объявление класса завершенным неявно делает завершенными и все его методы. Одновременное объявление класса, как abstract и final недопустимо.
final class А < //… >class B extends A/ ОШИБКА! Класс А не может иметь подклассы //… >
- Процедурное и объектно-ориентированное программирование
- Принципы ООП
- Классы и объекты
- Конструктор
- Ключевое слово this
- Перегрузка
- Стек и куча
- Передача объектов в методы
- Java varargs
- Рекурсия
- Сборщик мусора и метод finalize
- Наследование
- Ключевое слово super
- Модификаторы доступа
- Геттеры и сеттеры
- Переопределение методов
- Абстрактные классы и методы
- Задания
Локальная переменная final java
Вопрос глуппый но задам. Сборщик мусора не сходит сума при работе с immutable? Наример нам приходится в программе таскать 'с собой' масивы строк и паралельно в них менять значения. Это жесть какая нагрузка на железо.
public static void main(String[] args)
Вывод: I love Java I love Java Честно говоря, не понимаю, что удивительного в этом коде? Код же выполняется сверху вниз. А тут четверть статьи этому посвятили) Я так понимаю, что если я в конце в коде напишу: System.out.println(str1);, то вывод будет: I love Java I love Python Или я что-то не так понял?
Ведьмаку заплатите – чеканной монетой, чеканной монетой, во-о-оу Ведьмаку заплатите, зачтется все это вам
Всё что я должен понять из этой статьи: final для класса - класс нельзя наследовать, final для метода - метод нельзя переопределять, final для переменной - нельзя изменять первое присвоенное значение (сразу присваивать не обязательно), имя пишется капсом, слова через нижний пробел. Объекты всех классов обёрток, StackTrace, а также классы, используемые для создания больших чисел BigInteger и BigDecimal неизменяемые. Таким образом, при создании или изменении строки, каждый раз создаётся новый объект. Кратко о String Pool: Строки, указанные в коде литералом, попадают в String Pool (другими словами "Кэш строк"). String Pool создан, чтобы не создавать каждый раз однотипные объекты. Рассмотрим создание двух строковых переменных, которые указаны в коде литералом (без new String).
String test = "literal"; String test2 = "literal";
При создании первой переменной, будет создан объект строка и занесён в String Pool. При создании второй переменной, будет произведён поиск в String Pool. Если такая же строка будет найдена, ссылка на неё будет занесена во вторую переменную. В итоге будет две различных переменных, ссылающихся на один объект.
Мало примеров и в целом, недосказано. Под конец вскользь упомянут String Pool, а что это не объясняется. Статья озаглавлена какFinal & Co, а по факту пару примеров по строкам, ну, такое. Это называется собирались пироги печь, а по факту лепёшки лепим. В любом случае, конечно, спасибо за труд. Но, гораздо лучше про строки написано здесь: Строки в Java (class java.lang.String). Обработка строк в Java. Часть I: String, StringBuffer, StringBuilder (более детальная статья на Хабре).
Получается мы не можем создать поле какого нибудь класса не константой public static final String name = "Амиго"; обязательно только так? => public static final String CHARACTER_NAME = "Амиго"; или можно написать и так и так?
"В прошлых лекциях мы видели простой пример наследования: у нас был родительский класс Animal, и два класса-потомка — Cat и Dog" ?! А была лекция о наследовании?! Может быть я где-то пропустил, поделитесь ссылкой, пожалуйста 🙂
final и другие ключевые слова java
— Я расскажу тебе сегодня про несколько ключевых слов в Java. Но начну с самого интересного – ключевого слова 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 – если хотим сообщить другим разработчикам, что это значение – определенная константа, а не просто переменная.
Например, мы хотим рассчитать НДС от цены:
И во-вторых, если мы будем писать локальные или анонимные внутренние классы, то такие переменные нам понадобятся. Я расскажу о таких классах в ближайшее время. Но не сегодня.
— Ок, пока вроде ничего сложного.
— Обрати внимание, что неизменяемой становится только переменная, а не объект, на который она ссылается. Объект можно менять еще как.
— Как раз хотел уточнить этот момент. А нет способа сделать объект неизменным?
— Нет, только если ты напишешь immutable класс.
Обрати внимание на такой момент — т.к. значение переменной менять нельзя, то ей сразу нужно присвоить начальное значение:
class Home < private final int width; private final int height; public Home() < >>
Но, вместе с тем, Java разрешает перенести инициализацию final-переменных класса в конструктор.
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; > >
— Действительно интересная тема, и абсолютно все понятно, спасибо, Билаабо!