В каком порядке инициализируются переменные класса Java? - PullRequest
6 голосов
/ 26 января 2010

Я недавно сталкивался с этими вопросами и не смог найти ответ на StackOverflow;

  1. В каком порядке инициализируются переменные класса Java?
  2. И несколько связанный вопрос, может ли изменение порядка переменных изменить поведение класса?
  3. Почему?

Как указано в Meta Я буду публиковать свой ответ на этот вопрос.

1 Ответ

7 голосов
/ 26 января 2010

В Java переменные класса инициализируются в в следующем порядке :

  1. Статические переменные ваших суперклассов
  2. Все статические переменные этого класса имеют свои значения по умолчанию .
  3. Статические переменные и блоки статической инициализации в порядке объявления.
  4. Переменные экземпляра ваших суперклассов
  5. Все переменные экземпляра этого класса установлены на значения по умолчанию .
  6. Переменные экземпляра и блоки инициализации на уровне экземпляра в порядке объявления

1 & 2 выполняются только в первый раз, когда создается экземпляр класса.

Итак, учитывая следующий код:

class Test
  extends TestSuper
{
  final int ti1;
  final int ti2 = counter ++;
  { ti1 = counter ++; }
  static final int ts1;
  static final int ts2 = counter ++;
  static { ts1 = counter ++; }

  public static void main(String[] argv) {
    Test test1 = new Test();
    printTest(test1);
    Test test2 = new Test();
    printTest(test2);
  }
  private static void printTest(Test test) {
    System.out.print("ss2 = " + test.ss2);
    System.out.print(", ss1 = " + test.ss1);
    System.out.print(", ts2 = " + test.ts2);
    System.out.println(", ts1 = " + test.ts1);
    System.out.print("si2 = " + test.si2);
    System.out.print(", si1 = " + test.si1);
    System.out.print(", ti2 = " + test.ti2);
    System.out.println(", ti1 = " + test.ti1);
    System.out.println("counter = " + test.counter);
  }
}

class TestSuper
{
  static int counter = 0;
  final int si1;
  final int si2 = counter ++;
  { si1 = counter ++; }
  static final int ss1;
  static final int ss2 = counter ++;
  static { ss1 = counter ++; }
}

Тогда мы получим следующий вывод:

ss2 = 0, ss1 = 1, ts2 = 2, ts1 = 3
si2 = 4, si1 = 5, ti2 = 6, ti1 = 7
counter = 8
ss2 = 0, ss1 = 1, ts2 = 2, ts1 = 3
si2 = 8, si1 = 9, ti2 = 10, ti1 = 11
counter = 12

Из этого вывода видно, что поля инициализируются в порядке, указанном в списке.

Теперь, что касается второго вопроса, может ли переупорядочение полей изменить поведение класса. Да, изменяя порядок полей, вы изменяете порядок инициализации полей. Теперь, в конкретном случае, когда все поля независимы, это не повлияет на наблюдаемое поведение, однако всякий раз, когда поля не являются независимыми, например, в приведенном выше коде, изменение порядка полей может изменить их инициализированные значения.

Например, если три строки:

  static final int ss1;
  static final int ss2 = counter ++;
  static { ss1 = counter ++; }

изменены на:

  static final int ss1;
  static { ss1 = counter ++; }
  static final int ss2 = counter ++;

Тогда вывод изменится на:

ss2 = 1, ss1 = 0, ts2 = 2, ts1 = 3
si2 = 4, si1 = 5, ti2 = 6, ti1 = 7
counter = 8

То есть ss2 и ss1 будут изменять значения.

Причина этого заключается в том, что это поведение указано в Спецификации языка Java .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...