[英]Java: Static initialization
你能解釋一下我之間的區別是什么:
public class Test {
public static final Person p;
static {
p = new Person();
p.setName("Josh");
}
}
和
public class Test {
public static final Person p = initPerson();
private static Person initPerson() {
Person p = new Person();
p.setName("Josh");
return p;
}
}
我一直使用第二個,但靜態初始化塊有什么區別嗎?
當然有技術差異(你可以在你的課程中多次調用靜態方法,你可以通過反射來調用它等)但是,假設你沒有做任何這種詭計,你是對的 - 這兩種方法實際上完全相同。
我也更喜歡基於方法的方法,因為它為代碼塊提供了一個很好的名稱。 但它幾乎完全是一種風格方法。
正如Marko所指出的那樣,基於方法的方法還用於分離創建Person的兩個問題,並將其分配給靜態變量。 使用靜態塊,這兩個東西被組合在一起,如果塊是非平凡的,則會損害可讀性。 但該方法的方法,該方法是專門負責創建對象,和靜態變量的initializion是專門負責采取這一方法的結果並將其分配給變量。
更進一步:如果我有兩個靜態字段,一個依賴於另一個,那么我將聲明兩個方法,並讓第二個方法將第一個變量作為顯式參數。 我喜歡保持我的靜態初始化方法完全沒有狀態,這使得更容易推斷出應該發生哪一個(以及它假定已經創建了哪些變量)。
所以,像:
public class Test {
public static final Person p = initPerson();
public static final String pAddress = lookupAddress(p);
/* implementations of initPerson and lookupAddress omitted */
}
這是從看說的很清楚,即(一)你不需要pAddress
初始化p
,和(b) 你需要p
初始化lookupAddress
。 實際上,如果您以相反的順序嘗試它們並且您的靜態字段是非final
,編譯器會給您一個編譯錯誤(“非法轉發引用”):
public static String pAddress = lookupAddress(p); // ERROR
public static Person p = initPerson();
使用靜態塊會丟失清晰度和安全性。 編譯得很好:
static {
pAddress = p.findAddressSomehow();
p = new Person();
}
...但它在運行時會失敗,因為在p.findAddressSomehow()
, p
的默認值為null
。
每次調用時都會執行靜態方法(第二個示例)。 靜態初始化塊(第一個示例)僅在初始化類時調用一次。
http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
私有靜態方法的優點是,如果需要重新初始化類變量,它們可以在以后重用。
這不計入final
實例,因為最終變量只能初始化一次。
initPerson需要在某個時刻調用,而靜態塊在創建Test對象時執行。
函數之前的靜態指定您可以通過在類名稱句柄本身上調用它來使用該函數。 例如,如果要在類之外創建一個Person對象,則可以編寫
Person p = Test.initPerson();
但是,兩者之間沒有明顯的區別,因為在這兩種情況下都可以訪問類外的對象p。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.