статическая переменная по умолчанию для инициализации в коде [duplicate]

Попробуйте:

<([^\s]+)(\s[^>]*?)?(?<!/)>

Он похож на ваш, но последний > не должен быть после косой черты, а также принимает h1.

39
задан Tom Brito 6 January 2017 в 15:11
поделиться

5 ответов

Поскольку статика инициализируется в порядке, указанном в исходном коде.

Проверьте это:

class MyClass {
  private static MyClass myClass = new MyClass();
  private static MyClass myClass2 = new MyClass();
  public MyClass() {
    System.out.println(myClass);
    System.out.println(myClass2);
  }
}

Это напечатает:

null
null
myClassObject
null

EDIT

Хорошо, давайте сделаем это более понятным.

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

Является ли это ясно?

EDIT 2

Как указал Варман, ссылка на себя будет нулевой пока он инициализируется. Что имеет смысл, если вы думаете об этом.

33
ответ дан Gray 16 August 2018 в 04:35
поделиться
  • 1
    .. и потому что myClass сам статичен. – BalusC 30 March 2010 в 19:44
  • 2
    ok, static инициализируется по порядку. И статика перед конструктором, поэтому почему она не инициализируется при запуске конструктора? На самом деле выглядит как ошибка для меня .. – Tom Brito 31 March 2010 в 13:59
  • 3
    @ Тома, нет, вы поняли это неправильно. статики не находятся перед конструкторами. statics являются init, когда конструкторы называются соответственно. В моем примере, когда первый статический объект init с MyClass вызывается конструктором. Когда конструктор работает, myClass является init (потому что он работает сам), но myClass2 - нет. Когда второй MyClass является init, он вызывает конструктор снова, и на этот раз myClass уже был init, а myClass2 в это время является init – Pyrolistical 31 March 2010 в 18:32
  • 4
    поэтому аналогичная статика инициализируется в другом потоке, пока выполняется конструктор? У вас есть ссылка на тот же текст, подробно объясняющий это? – Tom Brito 31 March 2010 в 21:55
  • 5
    @Pyrolistical: Когда я выполнил вашу программу, у меня получился другой результат. Он напечатал null null myClassObjectref null – Vaman Kulkarni 24 March 2012 в 17:21

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

0
ответ дан antony 16 August 2018 в 04:35
поделиться
  • 1
    это не отвечает, почему оно равно нулю во время конструктора. – Tom Brito 31 March 2010 в 13:46

@Pyrolistical

, так как исходный первый статический класс myclass не полностью построен ... результат i get is

null null testInitialize.MyObject@70f9f9d8 null

0
ответ дан iamx7777777 16 August 2018 в 04:35
поделиться

Попробуем другой способ объяснить это ...

Это последовательность, которую JVM проходит, когда вы впервые ссылаетесь на класс MyClass.

  1. Загрузить байт-код в память.
  2. Память для статического хранилища очищается (двоичный ноль).
  3. Инициализировать класс: выполнить каждый статический инициализатор в том порядке, в котором он отображается, включая статические переменные и static { ... }. Затем JVM инициализирует старую переменную myClass в новом экземпляре MyClass. Когда это произойдет, JVM замечает, что MyClass уже загружен (байт-код) и в процессе инициализации, поэтому он пропускает инициализацию. Выделите память на кучу для объекта. Выполнить конструктор. Распечатайте значение obj, которое все еще null (так как оно не является частью инициализированных переменных кучи и конструктора). Когда конструктор заканчивается, выполните следующий статический инициализатор, который устанавливает obj в новый экземпляр Object.
  4. Выполнение инициализации класса. С этого момента все вызовы конструктора будут вести себя так, как вы предполагаете / ожидаете - это obj не будет null, а ссылкой на экземпляр Object.

Помните, что Java указывает, что переменной final присваивается значение один раз. Дело не в том, что гарантированно присваивается значение, когда код ссылается на него, если вы не убедитесь, что код ссылается на него после его назначения.

Это не ошибка. Это определенный способ обработки использования класса во время его собственной инициализации. Если бы это было не так, то JVM переходила бы в бесконечный цикл. См. Шаг № 3.3 (если JVM не пропускает инициализацию для класса, который находится в процессе инициализации, он просто сохранит его инициализацию - бесконечный цикл).

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

21
ответ дан Kevin Brock 16 August 2018 в 04:35
поделиться
  • 1
    Хороший ответ Кевин, лучший здесь – Newtopian 1 April 2010 в 02:54
  • 2
    Вы имеете в виду, что он пропускает «статические». инициализация, я полагаю. – zgulser 29 March 2016 в 14:31

Это потому, что Java выполняет статический раздел, чтобы он был объявлен. В вашем случае последовательность

  1. new MyClass
  2. new Object

Когда # 1 выполняется, obj все еще не инициализирован , поэтому он печатает нуль. Попробуйте следующее, и вы увидите разницу:

class MyClass {
  private static final Object obj = new Object();
  private static MyClass myClass = new MyClass();
  public MyClass() {
    System.out.println(obj); // will print null once
  }
}

Вообще говоря, лучше избегать такой конструкции все вместе. Если вы пытаетесь создать синглтон, вот как выглядит этот фрагмент кода:

class MyClass {

  private static final MyClass myClass = new MyClass();

  private Object obj = new Object();

  private MyClass() {
    System.out.println(obj); // will print null once
  }
}
19
ответ дан Slava Imeshev 16 August 2018 в 04:35
поделиться
  • 1
    +1 - хороший ответ. – JonH 30 March 2010 в 19:46
  • 2
    Правильно о & lt; clinit & gt; исполнение заказ. Синглтон на самом деле не синглтон, поскольку конструктор является публичным. – Rob Heiser 30 March 2010 в 19:57
  • 3
    Роб - спасибо за указание - исправлено. – Slava Imeshev 30 March 2010 в 20:02
  • 4
    ok, статичность инициализируется по порядку. И статика объявляется и запрашивается инициализировать перед конструктором, поэтому почему она не инициализируется при запуске конструктора? На самом деле выглядит как ошибка для меня .. – Tom Brito 31 March 2010 в 13:59
  • 5
    Статические элементы являются , построенные до запуска конструктора экземпляра. Это просто в вашем коде, ваш статический инициализатор также вызывает ваш конструктор. Это проблема с курицей и яйцом. – Dean Harding 31 March 2010 в 23:26
Другие вопросы по тегам:

Похожие вопросы: