2014-02-15 106 views
2

我進入了一種情況,希望有條件地加載和解析類。加載它與獲取正確的ClassLoader的句柄並調用loadClass方法一樣簡單。在調用loadClass方法後,我得到了一個我想加載的類的有效句柄。但是,目標類的靜態初始化程序沒有被調用,因爲該類直到後來才被解析。不幸的是,類靜態初始化程序註冊了重要的回調函數。下面顯示了一個例子。Java確保類已解決

public class ClassA 
{ 
    public static void main(String[] args) throws Throwable 
    { 
     Class<?> classB = ClassA.class.getClassLoader().loadClass("ClassB"); 
     System.out.println(classB.getName()); 
    } 

} 

public class ClassB 
{ 
    static 
    { 
     System.out.println("Class B initializer."); 
    } 
} 

在這個例子中運行ClassA的的輸出當然是:ClassB

我已經找到了一個臨時的解決方法是(在我看來)一個黑客位 的,那就是叫不重要在ClassB中強制類被解析的靜態函數。該方法如下所示。

public class ClassA 
{ 
    public static void main(String[] args) throws Throwable 
    { 
     Class<?> classB = ClassA.class.getClassLoader().loadClass("ClassB"); 
     classB.getMethod("something").invoke(null); 
     System.out.println(classB.getName()); 
    } 
} 

public class ClassB 
{ 
    static 
    { 
     System.out.println("Class B initializer."); 
    } 
    public static void something(){} 
} 

此方法的輸出(如預期):

Class B Initializer. 
ClassB 

這種方法有它因此我必須依靠具有公共靜態函數的類,並且擔心很多問題調用該函數的任何副作用。是否有更合法的方式來強制課堂解決?

+0

不要在控制檯的時間依靠100%。我看到它運行得很快,而且我看到它運行得很慢。它需要按收到的順序輸出所有內容。甚至有時當gc運行時,它暫停控制檯輸出並輸入一兩秒鐘 – mrres1

+0

我不明白的是爲什麼你需要返回「B類初始值設定項」。必須有一個更快的方式來做你目前正在用古代靜態塊扼殺的東西lol – mrres1

+0

你是什麼意思'返回「B類初始化程序」?並以什麼方式靜態塊緩慢 –

回答

3

你可以使用Class.forName(..)來初始化你的類並獲得對其Class對象的引用。

Class<?> classB = Class.forName("ClassB"); 

的Javadoc狀態

forName("X")調用導致命名X類被初始化。

相關:

+0

this.works在我的例子。這是否也適用於自定義類加載器加載的類? –

+0

@SE有一個接受'ClassLoader'的重載方法。 –

+0

聽起來不錯。我會在6分鐘內接受。該頁面說我必須等待 –