我认为我在这里弄错了。
我有一个简单的servlet
,带有一个打印一些消息的静态块。因此,据我所知,当servlet类首次加载到jvm时,应该处理静态块。
我正在使用嵌入式jetty
并使用-verbose:class
jvm选项启动jetty服务器。
我可以在输出中看到,在我第一次访问此servlet并查看消息之前很久就加载了Servlet
类。
但据我了解,静态块应该在加载类之后立即初始化。我在哪里错了?
答案 0 :(得分:2)
现在......当你说加载了Servlet
类时,你指的是你自己的类还是javax.servlet.Servlet
接口?
如果您没有在web.xml中的servlet声明中指定<load-on-startup>
并将其设置为非零值,则jetty只是跟随Servlet specification并且不加载它直到它为止第一次使用。
(以下是我在开始查看Servlet规范之前首先编写的内容,根据您是否<load-on-startup>
设置为非零值,它可能仍然相关)
根据Java规范§8.7
Java规范的在类初始化时执行类中声明的静态初始化程序(第12.4.2节)。
§12.4.1(§12.4.2的概述)说,如果发生以下某种情况,则会初始化类T
:
T
是一个类,并创建了T
的实例。T
是一个类,调用T
声明的静态方法。T
声明的静态字段。T
声明的静态字段,该字段不是常量变量(§4.12.4)。T
是顶级类(第7.6节),并且执行在T
(第8.1.3节)内词法嵌套的断言语句(第14.10节)。因此,如果jetty实际上从未对类执行任何操作,则静态初始化程序将无法运行
答案 1 :(得分:2)
Java虚拟机动态加载,链接和初始化 类和接口。 加载是查找二进制文件的过程 具有特定名称和类的类或接口类型的表示 从该二进制表示创建一个类或接口。链接 是一个获取类或接口并将其组合到一起的过程 Java虚拟机的运行时状态,以便它可以 执行。 类或接口的初始化包括执行 类或接口初始化方法
<clinit>
(§2.9)。
最后一部分<clinit>
是运行static
初始值设定项的地方。
-verbose:class
简单地
显示有关每个已加载类的信息。
因此,您的类是作为加载类路径条目的Web应用程序的一部分加载的,但是在Jetty实例化它之前它不会被初始化,以便它可以使用该对象来处理请求。