Java: В чем разница между <init>и <clinit>? - PullRequest
82 голосов
/ 15 декабря 2011

Я не могу понять следующий текст ... Означает ли это, что <clinit> для пустых конструкторов?Почему важно иметь две разные версии?

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html

2.9. Special Methods

На уровне виртуальной машины Java каждый конструктор (§2.12) отображается как инициализация экземпляраметод, имеющий специальное имя <init>.Это имя предоставлено компилятором.Поскольку имя <init> не является допустимым идентификатором, его нельзя использовать непосредственно в программе, написанной на языке программирования Java.Методы инициализации экземпляра могут вызываться только внутри виртуальной машины Java с помощью инструкции invokespecial, и они могут вызываться только для экземпляров неинициализированного класса.Метод инициализации экземпляра принимает права доступа (§2.7.4) конструктора, из которого он был получен.

Класс или интерфейс имеют не более одного метода инициализации класса или интерфейса и инициализируются (§2.17.4) вызывая этот метод.Метод инициализации класса или интерфейса является статическим и не принимает аргументов.У него есть специальное имя <clinit>.Это имя предоставлено компилятором.Поскольку имя <clinit> не является допустимым идентификатором, его нельзя использовать непосредственно в программе, написанной на языке программирования Java.Методы инициализации класса и интерфейса неявно вызываются виртуальной машиной Java;они никогда не вызываются напрямую из любой виртуальной машины Java inw2struction, но вызываются только косвенно как часть процесса инициализации класса.

Ответы [ 4 ]

123 голосов
/ 15 декабря 2011

<init> (или один из) конструктора (ов) для экземпляра и инициализация нестатического поля.

<clinit> - это статические блоки инициализации для класса и инициализация статического поля.

class X {

   static Log log = LogFactory.getLog(); // <clinit>

   private int x = 1;   // <init>

   X(){
      // <init>
   }

   static {
      // <clinit>
   }

}
21 голосов
/ 15 декабря 2011

<init> обозначает конструктор, <clinit> обозначает статический инициализатор : «Статические блоки инициализации» в руководстве по Java , Статический инициализатор в Java .

12 голосов
/ 15 декабря 2011

Разница между <init> и <clinit> заключается в том, что <init> используется для методов конструктора, которые инициализируют экземпляр объекта, тогда как <clinit> используется для инициализации самого объекта класса. Например, инициализация любых static полей уровня класса выполняется в <clinit>, когда класс загружается и инициализируется.

1 голос
/ 28 апреля 2017

Просто добавить Если вы используете метод Class.forName, он только инициализирует класс.Таким образом, из этого метода он вызывает только для Clinit, и когда вы используете newInstance для объекта, возвращенного из forName, он будет вызывать init для инициализации экземпляра.Вы можете использовать код ниже, чтобы увидеть его в отладке.

public class ByteCodeParent
{
 public static String name="ByteCode";
 public ByteCodeParent()
{
    System.out.println("In Constructor");
}

 static
 {
     System.out.println("In Static");
 }

 {
     System.out.println("In Instance");
 }

Для тестирования используйте

   Class<ByteCodeParent> bcp2 =(Class<ByteCodeParent>) Class.forName("ByteCodeParent");
ByteCodeParent bcp4= bcp2.newInstance();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...