2016-11-24 68 views
1

我有一類學生是的Java class.forClass()VS類聲明

package org.ahmed; 

public class Student { 

    public Student() { 
     // TODO Auto-generated constructor stub 
     System.out.println("Generated constructor"); 
    } 

    static { // static block 
     System.out.println("Hello world static"); 
    } 

    { // insance block 
     System.out.println("Hello world non static"); 
    } 
} 

然後

public class Main { 

    public static void main(String[] args) throws ClassNotFoundException { 
     Class.forName("org.ahmed.Student"); // this line causing static block execution in Student class 
     // Student s; // this line doesn't execute the static block. 
    } 
} 

我用Class.forClass()我們可以動態運行在運行任何 類明白。但在其他情況下,我有一些關於 靜態塊的問題。

如果我在我的main方法中使用Class.forClass("org.ahmed.Student"),那麼它的執行Student的靜態塊爲 。但是,如果我在 main方法中聲明Student s它不執行靜態塊。我認爲 Class.forClass("ClassName")是相同的聲明類與變量 名稱。

+0

實際上,它是'Class.forName()',而不是'Class.forClass()'。 –

回答

2

當您使用Class.forName("org.ahmed.Student")你居然強制JVM加載類和調用其靜態塊。您可以閱讀更多here

+0

因此,如果我只是用變量名聲明類引用,那麼靜態執行是不能保證的?像學生的? –

-1

聲明類引用將類加載到JVM,因此將執行靜態塊。我能看到

Student s; 

實施例的靜態塊執行:

package com.snofty.test; 

公共類類加載{

public ClassLoading(){ 
    System.out.println("in constructor"); 
} 
static { 
    System.out.println("in static block"); 
} 

{ 
    System.out.println("in instance block"); 
} 
public static void main(String[] args) { 
    ClassLoading classLoading; 

} 

}

Class.forName() 

它是用來加載該類動態地通過傳遞cl屁股名稱 例如

public void loadClass(String className){ 
    Class.forName(className); 
} 
+1

學生,在我的情況下不會導致靜態執行!!! –

+0

我的不好..我正在執行相同類的ClassLoaderTest類中的主要方法,因此能夠看到靜態塊執行.. – snofty

1

javadoc

調用Class.forName(className)方法是 等效於:Class.forName(className, true, currentLoader),其中第二參數指定類是否將被初始化。

所以,如果你不想初始化類,只需要調用與初始化方法=假,如:

Class.forName("org.ahmed.Student", false, this.getClass().getClassLoader())} 
+0

感謝您的答案。 –

3

裝載類(JLS§5.3而且我認爲,JLS§5.4)和之間的區別初始化類(JLS§5.5)。默認情況下,Class.forName既可以,但有an override you can use可讓您控制是否初始化該類。

只聲明一個Student變量不會初始化該類。實際上,即使是指Student.class也不會初始化這個類。你必須做一些事情來觸發初始化,如使用newgetstaticputstatic,或invokestatic字節碼操作與類的東西(但看到§5.5鏈接查看詳情,有初始化類其他東西)。

因此,舉例來說,如果你給Student公共領域:

public static String foo = "bar"; 

...然後在Main.main你這樣做:

System.out.println(Student.foo); 

... 將引發的初始化班上。

+0

感謝您的回答。 @ T.J。克勞德 –