2011-12-15 39 views
70

我無法理解以下文本......這是否意味着<clinit>用於空構造函數?爲什麼重要的是有兩個不同的版本?Java:<init>和<clinit>和有什麼不一樣?

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

2.9. Special Methods 

在Java虛擬機的水平,每一個構造函數(§2.12)顯示爲具有 特殊名稱<init>實例初始化方法。該名稱由編譯器提供。由於 名稱<init>不是有效的標識符,因此不能直接在用Java編程語言編寫的 程序中使用。實例 初始化方法可能僅在Java虛擬機的調用指令中被調用,並且它們可能僅在未初始化的類實例上調用 。實例初始化方法 具有構造函數的訪問權限(第2.7.4節),從中可以獲得它的派生名稱 。

一個類或接口最多隻有一個類或接口的初始化方法,並通過調用該方法初始化(§2.17.4)。類或接口的初始化方法是靜態的 並且不帶任何參數。它有一個特殊名稱<clinit>。這個名字是由編譯器提供的 。由於名稱<clinit>不是有效的 標識符,因此它不能直接用於編程爲 Java編程語言的程序。類和接口初始化方法 由Java虛擬機隱式調用;它們從來不是從任何Java虛擬機inw2struction直接調用的 ,但是 只是作爲類初始化過程的一部分被間接調用。

回答

107

<init>是實例和非靜態字段初始化的(或其中之一)構造函數。

<clinit>是類的靜態初始化塊和靜態字段初始化。

class X { 

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

    private int x = 1; // <init> 

    X(){ 
     // <init> 
    } 

    static { 
     // <clinit> 
    } 

} 
+2

是什麼`CL`立場? – 2015-07-11 13:52:16

12

<init><clinit>之間的區別是,<init>用於那些初始化對象實例構造方法,而<clinit>用於初始化類對象本身。例如,當類加載並初始化時,任何static級別字段的初始化在<clinit>中完成。

0

只需添加 如果您使用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(); 
相關問題