如何强制一个类初始化?

Art*_*tem 41 java coding-style static-initializer

什么是最好,最干净的方法?具体来说,我需要静态初始化程序块中的一些代码才能在该类中运行,但我希望尽可能使它看起来更干净.

L̲̳*_*̲̳̳ 47

正在加载!=初始化.

您希望初始化您的类(这是在执行静态块时).

Java语言规范的摘录说:

类或接口类型T将在第一次出现之前立即初始化>以下任何一个:

  • T是一个类,并且创建了T的实例.
  • T是一个类,并且调用由T声明的静态方法.
  • 分配由T声明的静态字段.
  • 使用由T声明的静态字段,该字段不是常量变量(第4.12.4节).
  • T是顶级类,并且执行在词典内嵌套在T中的断言语句(第14.10节).

在类Class和包java.lang.reflect中调用某些反射方法也会导致类或接口初始化.在任何其他情况下,不会初始化类或接口.

Doh,anovstrup,已经说过:只需要调用一个空的静态函数init.一定要记录好...我个人在格式良好的代码的上下文中看不到任何用例.

  • +1引用规范! (5认同)
  • 那么出于性能原因这样做呢?例如,在显示启动画面时强制进行静态初始化? (2认同)

小智 16

您可以使用以下代码强制初始化类:

//... Foo.class ...          //OLD CODE
... forceInit(Foo.class) ... //NEW CODE

/**
 * Forces the initialization of the class pertaining to 
 * the specified <tt>Class</tt> object. 
 * This method does nothing if the class is already
 * initialized prior to invocation.
 *
 * @param klass the class for which to force initialization
 * @return <tt>klass</tt>

 */
public static <T> Class<T> forceInit(Class<T> klass) {
    try {
        Class.forName(klass.getName(), true, klass.getClassLoader());
    } catch (ClassNotFoundException e) {
        throw new AssertionError(e);  // Can't happen
    }
    return klass;
} 
Run Code Online (Sandbox Code Playgroud)

  • Midnightas,不,我刚刚检查了Java 8:既没有".class"也没有".class.getName()"加载这个类."Class.forName"确实如此. (3认同)

Big*_*c66 8

try
{
  Class.forName(class name as string)
}
catch(ClassNotFoundException e)
{
  whatever
}
Run Code Online (Sandbox Code Playgroud)

应该这样做.

@Longpoke

也许我误解了一些事情.你能创建一个加载类但是执行静态初始化程序的例子吗?这是一个示例,除了打印出已加载之外什么都不做:

package test;

public class TestStatic 
{
    public static void main(String[] args) 
    {
        try 
        {
            Class.forName("test.Static");
        }
        catch (ClassNotFoundException e) 
        {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

加载以下静态类:

package test;

public class Static 
{
    static
    {
        System.out.println("Static Initializer ran...");
    }
}
Run Code Online (Sandbox Code Playgroud)

如果在您列出的条件满足之前没有运行静态初始值设定项,那么为什么在运行测试时这个println会被执行?那是我遇到的哪些条件?

  • 您可以使用重载形式的Class.forName <http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String,boolean, java.lang.ClassLoader)>.第二个参数确定是否要初始化类.另一种可能性是使用Static.class来获取对类的引用,这不会引发初始化. (4认同)
  • 非常感谢您向我解释!我从未使用过forName()的另一种形式,并且不知道单个参数形式将initialize标志默认为true.我的回答仍然有效,因为它会导致静态初始化程序执行,这是我相信Artem所追求的.我建议的表单加载*AND*显式初始化类.经过这么多年,我还在学习新事物...... (3认同)