Блоки инициализации в Java - Часть 1
- Данная статья написана командой Vertex Academy.
- Это одна из статей из нашего "Самоучителя по Java"
Привет! В данной статье мы расскажем самое-самое основное про блоки инициализации в Java. Но у этой статьи будет продолжение - часть 2, в которой будут описаны более сложные аспекты. Приятного прочтения!
Что такое инициализация
Для того, чтобы понять, что такое блоки инициализации, давайте сначала разберемся что такое инициализация. Кстати, этот вопрос Вам могут задать на собеседовании! Так что, даже если Вы уже знаете, что это - давайте повторим.
Инициализация (от англ. initialize, от initial - "начальный, первоначальный") - это когда мы впервые задаем переменной какое-либо значение.
Например, у нас есть переменная:
1 |
int i; |
Переменная есть, но пока в ней ничего не лежит. Мы ее не инициализировали - другими словами, не задали начальное, стартовое значение. Если попытаться сейчас вывести её на экран:
1 2 3 4 5 6 7 8 |
public class Test { public static void main(String[] args) { int i; System.out.println(i); } } |
Мы получим ошибку "переменная не инициализирована":
Но если мы инициализируем переменную - например, зададим значение 25:
1 2 3 4 5 6 7 8 9 |
public class Test { public static void main(String[] args) { int i; i = 25; System.out.println(i); } } |
Тогда ошибки не будет - увидим в консоли 25:
А все потому, что переменная больше не "пустая" - теперь у нее есть значение. Она была инициализирована. Отлично - теперь давайте перейдем к самим блокам.
Привычные способы инициализации
Как видите, для корректной работы программы переменным нужно задавать начальные значения. Мы уже привыкли это делать в середине метода - например вот так - для массивов:
или, например, в цикле:
Внутри класса, мы можем это делать так (возьмем пример из статьи "Конструкторы в Java"):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Dog{ private String name; private String poroda; private int age; public Dog(String x, String y, int z){ name = x; poroda = y; age = z; } } |
Тут у нас, как видите, есть класс Dog, у которого три параметра - имя (name), порода (poroda) и возраст (age). Мы инициализируем значения только при вызове конструктор Dog:
Иногда для инициализации мы используем сеттеры. Но есть и альтернативный способ - используя блоки инициализации.
Инициализация с помощью блоков
Представим, что мы хотим задать базовые значения переменных. Можно сделать это так:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Dog{ private String name = "Шарик"; private String poroda = "овчарка"; private int age = 2; public Dog(String x, String y, int z){ name = x; poroda = y; age = z; } } |
А можно использовать блок инициализации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Dog{ private String name; private String poroda; private int age; { name = "Шарик"; poroda = "овчарка"; age = 2; } public Dog(String x, String y, int z){ name = x; poroda = y; age = z; } } |
Видите - две фигурные скобки, между которыми мы присвоили новые значения переменным:
Выглядит лучше, правда? 🙂
Давайте посмотрим какие существуют блоки инициализации.
Виды блоков инициализации
Существует всего два типа блоков:
- нестатический (instance initializer)
- статический (class initializer)
В предыдущем примере Вы видели первый тип - нестатический блок инициализации. Его общую форму можно показать так:
1 2 3 |
{ //... } |
Второй тип - статический блок. Внешне он совсем немного отличается от первого типа - только нужно дописать слово static:
1 2 3 |
static { //... } |
Как можно догадаться по названию:
- статический блок используется для инициализации статических переменных, а "обычный" - для всех остальных.
Зачем используются блоки инициализации
Красивый и читабельный код - это конечно хорошо. Но зачем они нужны? Есть ли другие преимущества у блоков инициализации?
Есть. И это - больший функционал.
Внутри блоков инициализации мы можем не только присваивать значения. Это как метод - тут можно писать любые команды. Например, вывод в консоль:
1 2 3 4 5 6 7 |
class Test{ { System.out.println("Это нестатический блок!"); } } |
Для того, чтобы Вы могли протестировать у себя на компьютере, возьмем такой код (все тот же класс Dog):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Dog{ private String name; private String poroda; private int age; { System.out.println("Это нестатический блок инициализации!"); } public Dog(String x, String y, int z){ name = x; poroda = y; age = z; } } |
Теперь в нашем блоке инициализации есть только System.out.println("Это нестатический блок инициализации!"). Запустим его со следующим main-ом:
1 2 3 4 5 6 |
public class Test { public static void main(String[] args) { Dog d = new Dog("Шарик", "овчарка", 2); } } |
И получим в консоли:
Как видите, работает. Если бы мы просто написали System.out.println, без блока инициализации, программа бы не запустилась:
Как видите, такое можно делать только внутри блока инициализации. Это особенно полезно если нам нужно производить какие-нибудь вычисления перед инициализацией переменных.
Подводим итог:
- блоки инициализации используются для инициализации переменных внутри класса;
- есть два типа блоков инициализации - статический и нестатический;
- синтаксис очень простой - просто пишем выражение внутри блока из двух скобок:
1 2 3 |
{ //... } |
или для статического:
1 2 3 |
static { //... } |
- статический блок инициализации используется для статических переменных, нестатический - для всех остальных;
- блоки инициализации делают код читабельнее, и позволяют вызывать любые методы.
Теперь Вы имеете понятие о блоках инициализации. Отлично! 🙂 Более тонкие нюансы мы рассматриваем во второй части статьи - продолжайте читать!
Понравилась наша статья? Приходите к нам учиться. Детальнее у нас на сайте.