2014-04-14 74 views
4

我認爲我在這裏遇到了問題。java -verbose:class顯示servlet已加載,但只有在訪問servlet時纔會初始化靜態內容

我有一個簡單的servlet與一個靜態塊,打印一些消息。所以據我瞭解,當servlet類首次加載到jvm時,應該處理靜態塊。

我正在使用嵌入式jetty並使用-verbose:class jvm選項啓動碼頭服務器。

我可以在輸出中看到Servlet類在我第一次訪問此servlet並查看消息之前很久才加載。

但據我瞭解,靜態塊應該在類加載後立即初始化。我在哪裏錯了?

回答

2

Java Language Specification狀態

Java虛擬機動態負載鏈接初始化 類和接口。 加載是找到具有特定名稱的類或接口類型的二進制 表示並從該二進制表示形式創建類或接口的過程。鏈接 是取類或接口並將其合併到Java虛擬機的運行時狀態以使其可以執行的 的過程。 類或接口的初始化由執行 類或接口初始化方法<clinit>(第2.9節)組成。

這最後一部分,<clinit>,是你static初始化中運行。

java launcher option您使用

-verbose:class 

簡單

約裝載每個類顯示信息。

因此,您的類作爲加載類路徑條目的Web應用程序的一部分加載,但直到Jetty實例化它才能使用該對象處理請求時纔會初始化它。

2

現在......當你說Servlet類被加載時,你指的是你自己的類還是指向javax.servlet.Servlet接口?

如果您沒有指定<load-on-startup>並將它設置爲servlet在web.xml中的聲明中的非零值,那麼jetty只是在Servlet specification之後,並且在第一次使用之前不加載它。


(下面是我會先寫之前,我開始看在Servlet規範,它可能仍然是相關的取決於如果您有<load-on-startup>設置爲非零值上)

根據Java規範§8.7

當類初始化時(§12.4.2),將執行在類中聲明的靜態初始化器。

§12.4.1 Java規範的(在§12.4.2的概述)表示當發生下列情況之一的一類T被初始化:

  • T是一個類並且創建的T一個實例。
  • T是一個類,調用了一個由T聲明的靜態方法。
  • 分配了一個由T聲明的靜態字段。
  • 使用由T聲明的靜態字段,該字段不是常量變量(§4.12.4)。
  • T是頂級類(第7.6節),並執行了在詞彙上嵌套在T(第8.1.3節)內的斷言語句(第14.10節)。

所以,如果碼頭從來沒有真正確實與類東西,靜態初始化將不會運行

相關問題