如何强制一个类初始化?

时间:2010-08-24 19:09:43

标签: java coding-style static-initializer

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

6 个答案:

答案 0 :(得分:45)

正在加载!=初始化。

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

Java Language Specification的摘录说:

  

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

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

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

Doh,anovstrup,已经说过:只需创建一个名为init的空静态函数。一定要记录得很好......我个人在格式良好的代码中看不到任何用例。

答案 1 :(得分:12)

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

//... 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;
} 

答案 2 :(得分:8)

try
{
  Class.forName(class name as string)
}
catch(ClassNotFoundException e)
{
  whatever
}

应该这样做。

@Longpoke

也许我误解了一些事情。您是否可以创建一个加载类但静态初始化程序执行的示例?这是一个只打印出已加载的例子:

package test;

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

加载以下静态类:

package test;

public class Static 
{
    static
    {
        System.out.println("Static Initializer ran...");
    }
}

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

答案 3 :(得分:4)

类之间的不可见依赖关系不是一个好主意。我建议将静态初始化程序块中的代码移动到静态方法并直接在依赖类中调用它。可以重写静态初始化程序块以调用新创建的静态方法。

答案 4 :(得分:1)

一种解决方案是调用静态方法:

public class A {
   static { DebugUtils.FLAG_TEST_USER = true; }

   static void init() {}
}

然后调用A.init()强制初始化。

然而,这样做就是代码味道。考虑用单个对象中的标准构造函数替换静态代码。

答案 5 :(得分:0)

如果你需要在类中静态启动某些东西,这意味着必须有依赖于它的客户端类。

如果有一个客户端,或者让它称之为初始化块的自然之家,我认为在那里初始化它是最干净的。

对于许多平等客户案例,从这些类中验证其他类中的静态初始化是否成功可能是个好主意。然后记录耦合,并确保在第一个客户端需要它之前始终初始化类。