Java 如何强制初始化一个类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3560103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to force a class to be initialised?
提问by Artem
What is the best and cleanest way to do this? Specifically, I need some code in a static initializer block to run in that class, but I'd like to make this as clean-looking as possible.
什么是最好和最干净的方法来做到这一点?具体来说,我需要静态初始化程序块中的一些代码才能在该类中运行,但我想让它看起来尽可能干净。
采纳答案by L??o???n???g???p??o???k???e???
Loading != Initialization.
正在加载 != 初始化。
You want your class to be initialized (this is when static blocks executed, among other things).
您希望您的类被初始化(这是在执行静态块时等等)。
An excerpt from the Java Language Specificationsays:
Java 语言规范的摘录说:
A class or interface type T will be initialized immediately before the first occurrence of >any one of the following:
- T is a class and an instance of T is created.
- T is a class and a static method declared by T is invoked.
- A static field declared by T is assigned.
- A static field declared by T is used and the field is not a constant variable (§4.12.4).
- T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.
Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.
类或接口类型 T 将在第一次出现 > 以下任何一项之前立即初始化:
- T 是一个类,并且创建了一个 T 的实例。
- T 是一个类,并且调用了一个由 T 声明的静态方法。
- 分配了由 T 声明的静态字段。
- 使用 T 声明的静态字段,该字段不是常量变量(第 4.12.4 节)。
- T 是一个顶级类,并且会执行在词法上嵌套在 T 中的 assert 语句(第 14.10 节)。
在类 Class 和包 java.lang.reflect 中调用某些反射方法也会导致类或接口初始化。在任何其他情况下都不会初始化类或接口。
Doh, anovstrup, already said it: Just make an empty static function called init
. Be sure to document that well... I personally can't see any use case for this in the context of well formed code though.
Doh,anovstrup,已经说过了:只需创建一个名为init
. 一定要好好记录......不过,我个人在格式良好的代码的上下文中看不到任何用例。
回答by Abhinav Sarkar
Invisible dependencies between classes is not a good idea. I suggest moving the code in static initializer block to a static method and calling it directly in the dependent class. The static initializer block can be rewritten to call the newly created static method.
类之间的不可见依赖不是一个好主意。我建议将静态初始化程序块中的代码移动到静态方法并直接在依赖类中调用它。可以重写静态初始化块以调用新创建的静态方法。
回答by BigMac66
try
{
Class.forName(class name as string)
}
catch(ClassNotFoundException e)
{
whatever
}
That should do it.
应该这样做。
@Longpoke
@Longpoke
Maybe I am misunderstanding something then. Can you create an example where a class is loaded but the static initializer is notexecuted? Here is an example that does nothing but print out that it has loaded:
也许我当时误解了一些东西。您能否创建一个加载类但未执行静态初始化程序的示例?这是一个示例,它只打印出它已加载:
package test;
public class TestStatic
{
public static void main(String[] args)
{
try
{
Class.forName("test.Static");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
With the following Static class being loaded:
加载以下静态类:
package test;
public class Static
{
static
{
System.out.println("Static Initializer ran...");
}
}
If the static initializers are not ran until the conditions you listed are met then why does this println get executed when I run my test? That is which of your listed conditions am I meeting?
如果在满足您列出的条件之前不运行静态初始值设定项,那么为什么在我运行测试时会执行此 println ?那是我满足您列出的哪个条件?
回答by Aaron Novstrup
One solution would be to call a static method:
一种解决方案是调用静态方法:
public class A {
static { DebugUtils.FLAG_TEST_USER = true; }
static void init() {}
}
Then invoke A.init()
to force initialization.
然后调用A.init()
强制初始化。
However, doing this at all is a code smell. Consider replacing your static code with a standard constructor in a singleton object.
然而,这样做是一种代码味道。考虑用单例对象中的标准构造函数替换静态代码。
回答by Peter Tillemans
If you need to statically initilize something in a Class that means there must be client classes dependent on that.
如果您需要静态初始化类中的某些内容,则意味着必须有依赖于此的客户端类。
If there is one client, or let's call it a natural home for the initializing block, I think it would be cleanest to initialize it there.
如果有一个客户端,或者让我们称其为初始化块的自然家园,我认为在那里初始化它是最干净的。
For the many equal clients case, it may be a good idea to verify from these classes that the static initalization in the other class was successful. Then the coupling is documented and you are sure the class is always initialized before the first client needs it.
对于许多相同客户端的情况,从这些类中验证其他类中的静态初始化是否成功可能是一个好主意。然后记录耦合并且您确定该类总是在第一个客户需要它之前被初始化。
回答by Iulian
You can use the following code to force initialization of a class:
您可以使用以下代码强制初始化类:
//... 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;
}