2014-02-15 100 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分钟内接受。该页面说我必须等待 –