Java: В чем разница между <init> и <clinit>?

Я не могу понять следующий текст... Означает ли это, что <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, но вызывается только косвенно как часть процесса инициализации класса.

Ответ 1

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

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

class X {

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

   private int x = 1;   // <init>

   X(){
      // <init>
   }

   static {
      // <clinit>
   }

}

Ответ 3

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

Ответ 4

Просто добавьте Если вы используете метод Class.forName, он только инициализирует класс. Поэтому из-за этого метода он делает вызов только в клинике, и когда вы используете 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();