Я не понимаю следующий текст ... Означает ли это, что <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, а вызываются только косвенно как часть процесса инициализации класса.
CL
?<init>
обозначает конструктор,<clinit>
обозначает статический инициализатор : «Блоки статической инициализации» в Руководстве по Java , Статический инициализатор в Java .источник
Разница между
<init>
и<clinit>
заключается в том, что<init>
он используется для методов конструктора, которые инициализируют экземпляр объекта, тогда как<clinit>
он используется для инициализации самого объекта класса. Например, инициализация любыхstatic
полей уровня класса выполняется,<clinit>
когда класс загружается и инициализируется.источник
Просто чтобы добавить. Если вы используете метод 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();
источник