我无法理解以下文字......这是否意味着<clinit>
适用于空构造函数?为什么重要的是有两个不同的版本?
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html
2.9. Special Methods
在Java虚拟机的级别上,每个构造函数(第2.12节)都显示为具有以下内容的实例初始化方法 特殊名称
<init>
。该名称由编译器提供。因为 名称<init>
不是有效的标识符,不能直接在a中使用 用Java编程语言编写的程序。例 初始化方法只能在Java虚拟内部调用 通过invokespecial指令机器,它们只能被调用 在未初始化的类实例上。实例初始化方法 获取构造函数的访问权限(第2.7.4节) 它来自。一个类或接口最多只有一个类或接口初始化方法,并通过调用它来初始化(第2.17.4节) 方法。类或接口的初始化方法是静态的 并且没有参数。它具有特殊名称
<clinit>
。这个名字是 由编译器提供。因为名称<clinit>
不是有效的 标识符,它不能直接用于编写的程序中 Java编程语言。类和接口初始化方法 由Java虚拟机隐式调用;他们永远不会 直接从任何Java虚拟机inw2struction调用,但是 仅作为类初始化过程的一部分间接调用。
答案 0 :(得分:122)
<init>
是实例的(或其中一个)构造函数,以及非静态字段初始化。
<clinit>
是类的静态初始化块,以及静态字段初始化。
class X {
static Log log = LogFactory.getLog(); // <clinit>
private int x = 1; // <init>
X(){
// <init>
}
static {
// <clinit>
}
}
答案 1 :(得分:21)
<init>
表示构造函数,<clinit>
表示静态初始化程序:"Static Initialization Blocks" in the Java Tutorial,Static initializer in Java。
答案 2 :(得分:12)
<init>
和<clinit>
之间的区别在于<init>
用于初始化对象实例的构造函数方法,而<clinit>
用于初始化类对象本身。例如,当类加载并初始化时,任何static
类级别字段的初始化都在<clinit>
中完成。
答案 3 :(得分:1)
只是添加 如果使用Class.forName方法,它只会初始化类。因此,在此方法中,它只调用clinit,当您对从forName返回的对象使用newInstance时,它将调用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();