为什么在java中加载JNI是在静态初始化器中完成的?

为什么在java中加载JNI是在静态初始化器中完成的?,java,java-native-interface,Java,Java Native Interface,在许多使用JNI的示例中,我看到如下内容: class SampleClass { static { System.loadLibrary("somelib"); } ... } 这种特殊语法的目的是什么?为什么要用这个(而且不仅仅是在类构造函数或类似的东西中?没有理由不这样做,但是通常您只希望加载本机库一次。实现这一点的最简单方法是通过静态初始值设定项。否则,您需要实现自己的机制,以防止它发生多次。有关重新加载库的信息,请参阅。 另一个原因是您无法使用

在许多使用JNI的示例中,我看到如下内容:

class SampleClass {
    static {
        System.loadLibrary("somelib");
    }
    ...
}

这种特殊语法的目的是什么?为什么要用这个(而且不仅仅是在类构造函数或类似的东西中?

没有理由不这样做,但是通常您只希望加载本机库一次。实现这一点的最简单方法是通过静态初始值设定项。否则,您需要实现自己的机制,以防止它发生多次。有关重新加载库的信息,请参阅。


另一个原因是您无法使用本机代码提供静态方法。

我认为您将从本书中得到最佳答案:

您可以在其中阅读:

在调用本机方法print之前 必须加载implements print。在本例中,我们加载本机 HelloWorld类的静态初始值设定项中的库 虚拟机在启动之前自动运行静态初始值设定项 调用HelloWorld类中的任何方法,从而确保 在调用print native方法之前加载本机库

通常,没有任何东西阻止您在class.method的方法内部加载库,该方法不是
静态的
。但在这种情况下,您必须确保在调用任何本机方法之前加载库(通过调用调用load或loadLibrary的方法)

另外,如果您想加载库的另一个版本,而不需要使用多个类加载器,您可以始终使用包装器代码。这样,您可以在本机代码实现之间动态切换


看看这里:

本身不会称之为特殊语法。所有静态字段的初始化都可以使用它来完成,并且也看到过使用classloader或基于配置的场景。它通常调用的代码是“每个类”,而不是每个实例。因为(1)您只想执行一次,以及(2)在构造函数中已经太晚了。基类中可能有静态本机方法,或实例本机方法,或…最后一行“动态加载JNI中的库”链接变为404。谢谢评论。我将更新它!