Java: < init > 和 < clinit > 有什么区别?

我无法理解下面的文本... 这是否意味着 <clinit>是空构造函数?为什么有两个不同的版本很重要?

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

2.9. Special Methods

在 Java 虚拟机的级别上,每个构造函数(2.12)都显示为一个实例初始化方法,该方法具有 特殊名称 <init>。此名称由编译器提供。因为 Name <init>不是有效标识符,不能直接在 用 Java 编程语言编写的程序 初始化方法只能在 Java 虚拟机中调用 机器,并且它们只能被调用 对未初始化的类实例。实例初始化方法 接受构造函数的访问权限(2.7.4) 它是派生出来的。

类或接口最多有一个类或接口初始化方法,通过调用该方法初始化(2.17.4) 类或接口的初始化方法是静态的 并且不接受任何参数。它有一个特殊的名称 <clinit>。这个名称是 由编译器提供。因为名称 <clinit>不是有效的 标识符中编写的程序中,不能直接使用 Java 编程语言。类和接口初始化方法 是由 Java 虚拟机隐式调用的; 它们从不 直接从任何 Java 虚拟机 inw2指令调用,但是 仅作为类初始化过程的一部分间接调用。

44264 次浏览

<init> is the (or one of the) constructor(s) for the instance, and non-static field initialization.

<clinit> are the static initialization blocks for the class, and static field initialization.

class X {


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


private int x = 1;   // <init>


X(){
// <init>
}


static {
// <clinit>
}


}

<init> denotes a constructor, <clinit> denotes a static initializer: "Static Initialization Blocks" in the Java Tutorial, Static initializer in Java.

The difference between <init> and <clinit> is that <init> is used for constructor methods that initialise an object instance, whereas <clinit> is used to initialise the class object itself. For instance initialisation of any static class level fields is done in <clinit> when the class is loaded and initalised.

Just to add If you use Class.forName method, it only intializes the class. So from within this method, it makes a call only to clinit and when you use newInstance on the object returned from forName, it will call init for the instance initialization. You can use below code to see it in debug.

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");
}

To test, use

   Class<ByteCodeParent> bcp2 =(Class<ByteCodeParent>) Class.forName("ByteCodeParent");
ByteCodeParent bcp4= bcp2.newInstance();