Java:<init>和<clinit>之间的区别是什么?</clinit> </init>

时间:2011-12-15 08:28:35

标签: java jvm

我无法理解以下文字......这是否意味着<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调用,但是   仅作为类初始化过程的一部分间接调用。

4 个答案:

答案 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 TutorialStatic 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();