类的静态块什么时候执行?

发布于 2025-01-02 09:34:17 字数 479 浏览 1 评论 0原文

我有 2 个 jar,我们称它们为 a.jar 和 b.jar。

b.jar 依赖于 a.jar。

在a.jar中,我定义了一个类,我们称之为StaticClass。在StaticClass中,我定义了一个静态块,调用一个名为“init”的方法:

public class StaticClass {
  static {
    init();
  } 

  public void static init () {
    // do some initialization here
  }
}

在b.jar中,我有一个main,因此在main中,我期望已调用init()方法,但实际上没有。我怀疑这是因为 StaticClass 尚未被 jvm 加载,有人能告诉我

  1. 我的结论是否正确?
  2. 什么触发jvm加载类?
  3. 如何让静态块自动执行?

谢谢

I have 2 jars, let's call them a.jar and b.jar.

b.jar depends on a.jar.

In a.jar, I defined a class, let's call it StaticClass. In the StaticClass, I defined a static block, calling a method named "init" :

public class StaticClass {
  static {
    init();
  } 

  public void static init () {
    // do some initialization here
  }
}

in b.jar, I have a main, so in the main, I expect that the init() method has been called, but actually not. I suspect that is because the StaticClass has not been loaded by the jvm, could anyone tell me

  1. Is my conclusion correct?
  2. What triggers the jvm to load a class?
  3. How can I get the static block executed automatically?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

榕城若虚 2025-01-09 09:34:17

是的你是对的。静态初始化块在 JVM(具体来说是类加载器)加载 StaticClass(在代码中第一次引用它时发生)时运行。

您可以通过显式调用 StaticClass.init() 强制调用此方法,这比依赖 JVM 更好。

您还可以尝试使用 Class.forName(String) 强制 JVM 加载该类并调用其静态块。

Yes, you are right. Static initialization blocks are run when the JVM (class loader - to be specific) loads StaticClass (which occurs the first time it is referenced in code).

You could force this method to be invoked by explicitly calling StaticClass.init() which is preferable to relying on the JVM.

You could also try using Class.forName(String) to force the JVM to load the class and invoke its static blocks.

灯下孤影 2025-01-09 09:34:17

首先,类加载与类初始化不同。对于任何从 Java 语言规范中寻找解释的人来说,静态块何时执行 - 就在这里。

JLS §8.7 说那 :

类中声明的静态初始值设定项会在类初始化时执行(第 12.4.2 节)。

那么初始化是什么意思呢?让我们参考 JLS §12.4。 2.。这描述了详细的初始化过程。但是,JLS §12.4.1 在这里可能更合适。它说:

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

  • T 是一个类,并且创建了 T 的实例。
  • T 是一个类,并且调用 T 声明的静态方法。
  • T 声明的静态字段被赋值。
  • 使用 T 声明的静态字段,并且该字段不是常量变量(第 4.12.4 节)。
  • T 是顶级类(第 7.6 节),并且执行词法嵌套在 T(第 8.1.3 节)内的断言语句(第 14.10 节)。
  • 因此,要使静态初始化块自动执行,您必须强制执行这些选项之一。

    First of all class loading is different than class initialization. For anyone looking for explanation from Java Language Specification, when is static block executed - here it is.

    The JLS §8.7 says that :

    A static initializer declared in a class is executed when the class is initialized (§12.4.2).

    So what does the initialization mean? Let's refer to JLS §12.4.2. This describes detailed initialization procedure. However point JLS §12.4.1 might be more appropriate here. It says that :

    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 (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

  • So to make the static initializer block to be executed automatically, you have to force one of those options to happen.

    栩栩如生 2025-01-09 09:34:17

    是的,你是对的,因为你没有使用 StaticClass 它不会被虚拟机加载,因此 init() 永远不会被执行。

    对于第二个问题,您可能必须采取艰难的方式并扫描所有可用的类并加载它们。

    https://stackoverflow.com/a/3223019/393657

    Yes you are right, since you are not using your StaticClass it is not loaded by the vm and therefore init() is never executed.

    For your second question, you probably have to go the hard way and scan all available classes and load them.

    https://stackoverflow.com/a/3223019/393657

    北恋 2025-01-09 09:34:17

    静态块在首先初始化或引用加载的类时执行。加载类并不意味着该类将被初始化。 JVM 类加载是需要关注的单独的事情。

    Static block is executed when a loaded class is initialized or referenced first. Loading class doesnt mean that class is to initialized. JVM Class Loading is separate things to concern.

    新一帅帅 2025-01-09 09:34:17

    你是对的,最简单的方法是访问该类,例如在你的 main 方法中执行

    StaticClass.class.newInstance();

    或类似的操作。这将确保类由类加载器加载。

    You are right, the easiest way is to access the class, for instance do a

    StaticClass.class.newInstance();

    Or something to that respect in your main method. This will ensure the class is loaded by the classloader.

    旧人 2025-01-09 09:34:17

    当您的类(我猜是StaticClass)被引用时,静态代码就会被执行。

    因此,如果您创建 StaticClass新实例或者调用其静态方法之一,则应该执行它。

    The static code is executed when your class (StaticClass I guess) is referenced.

    Thus, it should be executed if you create a new instance of StaticClass or if you call one of its static methods.

    悍妇囚夫 2025-01-09 09:34:17

    是的,静态初始化器将在类加载时执行。当您第一次访问类加载上下文中的类时,通常会发生这种情况。

    Yes, the static initializer will be executed when the class is loaded. This normally occurs when you access the class in the class loading context for the first time.

    神仙妹妹 2025-01-09 09:34:17

    在 b.jar 中,主方法类应该扩展该 StaticClass,然后自动调用静态块和 init()

    in b.jar main method class should extend that StaticClass then automatically that static block and init() will be invoked

    幻梦 2025-01-09 09:34:17

    添加一些:

    静态块将在jvm加载类时执行。

    在您的示例中,您可以通过实例化类来调用 StaticClassinit() 方法

    ,例如
    StaticClass staticClass=new StaticClass();

    StaticClass.class.newInstance(); 这更可取

    Adding some more:

    static block will be executed when jvm load class.

    Here in your example you can call init() method of your StaticClass by intantiating class

    like
    StaticClass staticClass=new StaticClass();

    or

    StaticClass.class.newInstance(); this is more preferebal

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文