Почему этот Java-код находится в фигурных скобках ({}) вне метода?
Я готовлюсь к экзамену по сертификации java, и я видел код LIKE this в одном из практических тестов:
class Foo {
int x = 1;
public static void main(String [] args) {
int x = 2;
Foo f = new Foo();
f.whatever();
}
{ x += x; } // <-- what up with this?
void whatever() {
++x;
System.out.println(x);
}
}
Мой вопрос... Является ли правильным писать код в фигурных скобках вне метода? Каковы последствия этих (если есть)?
Ответы
Ответ 1
Заимствован из здесь -
Обычно вы должны вводить код для инициализации переменной экземпляра в конструктор. Существует два варианта использования конструктора для инициализировать переменные экземпляра: блоки инициализации и конечные методы. Блоки инициализатора для переменных экземпляра выглядят так же, как статические инициализаторы, но без статического ключевого слова:
{
// whatever code is needed for initialization goes here
}
Компилятор Java копирует блоки инициализации в каждый конструктор. Поэтому этот подход может использоваться для совместного использования блока кода между несколькими конструкторами.
Вы также можете посмотреть обсуждения здесь.
Ответ 2
Это блок инициализатора, который выполняется, когда экземпляр класса загружается/создается и используется для инициализации свойств элемента класса (см. Java http://download.oracle.com/javase/tutorial/java/javaOO/initial.html). Вы можете иметь столько блоков, сколько хотите, и они будут создаваться сверху вниз.
В дополнение к блоку экземпляра вы можете иметь столько статических блоков, сколько хотите, чтобы инициализировать статические элементы. Они будут объявлены следующим образом:
public class Initialization {
static int b = 10;
int a = 5;
static {
b = -9;
}
{
a += 2;
}
public static void main(String[] args) throws Exception {
System.out.println(ClientVoting.b);
System.out.println(new ClientVoting().a);
System.out.println(ClientVoting.b);
System.out.println(new ClientVoting().a);
}
static {
b = 1;
}
{
a++;
}
}
Пока инициализируется класс, статический член "b" инициализируется как 10, тогда первая статическая область меняет свое значение на -9, а затем на 1. Это выполняется только один раз, когда класс загружается. Это выполняется до инициализации первой строки основного метода.
С другой стороны, аналогичным примером для вашего класса является ссылка на экземпляр "a". А инициализируется как 5, затем блок экземпляра обновляет его до 7, а последний - до 8. Как и ожидалось, статические члены инициализируются только один раз в этом коде, тогда как блоки экземпляров выполняются КАЖДЫЙ раз, когда вы создаете новый экземпляр.
Выход в этот пример равен 1 8 1 8
Ответ 3
Это блок инициализатор. Он использовался для установки переменных экземпляра. Мотивация использования блоков инициализатора над конструкторами заключается в предотвращении написания избыточного кода. Компилятор Java копирует содержимое блока в каждый конструктор.