Подтвердить что ты не робот

Почему этот 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);  
    }  
}

Мой вопрос... Является ли правильным писать код в фигурных скобках вне метода? Каковы последствия этих (если есть)?

4b9b3361

Ответ 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 копирует содержимое блока в каждый конструктор.