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

Java-независимый блок кода

Я давно работаю с Java, но никогда не сталкивался с чем-то подобным. Я хотел бы знать, что он делает и почему это не ошибка.

public class Foo{

 private int someVariable;

 {
    doSomething();
 }

 public Foo(){
 }

 private void doSomething(){
    // Something is done here
 }

}

Я хотел бы знать, какова цель отдельного блока, который содержит вызов "doSomething()". Его просто скелетный код. Фактический код, с которым я столкнулся, находится на http://www.peterfranza.com/2010/07/15/gwt-scrollpanel-for-touch-screens/

4b9b3361

Ответ 1

Это (нестатический) блок инициализатора. Это описано в официальном учебнике здесь:

Инициализация членов экземпляра

Обычно вы добавляете код для инициализации переменной экземпляра в конструкторе. Существует две альтернативы использованию конструктора для инициализации переменных экземпляра: блоки инициализации и конечные методы. Блоки инициализатора для переменных экземпляра выглядят так же, как и статические блоки инициализатора, но без статического ключевого слова:

{
    // whatever code is needed for initialization goes here
}

Компилятор Java копирует блоки инициализации в каждый конструктор. Поэтому этот подход может использоваться для совместного использования блока кода между несколькими конструкторами.


Вот простая демонстрация:

public class Test {

    {
        System.out.println("Initializer block");
    }

    Test() {
        System.out.println("Constructor 1");
    }

    Test(int i) {
        System.out.println("Constructor 2");
    }

    public static void main(String[] args) {
        new Test();
        System.out.println("---");
        new Test(1);
    }
}

Выход

Initializer block
Constructor 1
---
Initializer block
Constructor 2

Вы можете найти это полезным, если, например, добавить панель JLabel в панель:

panel.add(new JLabel() {{ setBackground(Color.GREEN); setText("Hello"); }});

Под капотом:

Байт-код блока инициализатора буквально копируется в каждый конструктор. (По крайней мере, Suns javac и компилятор eclipse:

Test();
  Code:
    0:  aload_0
    1:  invokespecial
    4:  getstatic #2;
    7:  ldc #3;           //String "Initializer block"
    9:  invokevirtual #4; //Method PrintStream.println:(String;)V
   12:  getstatic #2;
   15:  ldc #5;
   17:  invokevirtual #4;
   20:  return

Test(int);
  Code:
    0:  aload_0
    1:  invokespecial #1;
    4:  getstatic #2;
    7:  ldc #3;           //String "Initializer block"
    9:  invokevirtual #4; //Method PrintStream.println:(String;)V
   12:  getstatic #2;
   15:  ldc #6;
   17:  invokevirtual #4;
   20:  return

Ответ 2

Это блок инициализатора, который копируется во все конструкторы для класса.