[英]Final static variable initialized in static block using method that throws exception
[英]Can't define a private static final variable because it throws an exception
我有一個類:
public class SomeClassImpl implements SomeClass {
private static final SomeLib someLib = new SomeLib();
}
我不能這樣做,因為SomeLib會拋出一個UnknownHostException。
我知道我可以將實例化移動到構造函數中,但是我有辦法以某種方式以上面的方式執行它嗎? 這樣我就可以將var標記為final。
我試圖尋找如何在類級別拋出異常,但無法在其上找到任何內容。
您可以使用靜態初始化程序:
public class SomeClassImpl implements SomeClass {
private static final SomeLib someLib;
static {
SomeLib tmp = null;
try {
tmp = new SomeLib();
} catch (UnknownHostException uhe) {
// Handle exception.
}
someLib = tmp;
}
}
請注意,我們需要使用臨時變量來避免“變量someLib可能尚未初始化”錯誤,並且應對這樣一個事實,即由於它是final
,我們只能分配someLib
一次。
但是,需要向靜態初始化程序添加復雜的初始化邏輯和異常處理通常是更基本的設計問題的標志。 您在評論部分寫道,這是一個數據庫連接池類。 而不是使用靜態最終考慮使其成為實例變量。 然后,您可以在構造函數中進行初始化,或者更好地在靜態工廠方法中進行初始化。
您可以使用靜態初始化程序:
private static final SomeLib SOME_LIB; // respect naming conventions
static {
try {
SOME_LIB = new SomeLib();
}
catch (UnknownHostException e) {
throw new RuntimeException("Class initialization failed due to UnknownHostException", e);
}
}
請注意,如果您這樣做,您的課程將無法初始化。 也許你應該在需要時嘗試懶惰地初始化lib。 這樣的類初始化異常很難診斷,因為它們被轉換為ClassNotFoundException或NoClassDefFoundError(我不記得哪一個)
甚至比Adam Zalcman的解決方案更優雅一點:
public class SomeClassImpl implements SomeClass {
private static final SomeLib someLib = initSomeLib();
private static SomeLib initSomeLib() {
SomeLib someLib = null;
try {
someLib = new SomeLib();
} catch (UnknownHostException uhe) {
// Handle exception.
}
return someLib;
}
}
此示例代碼將為您提供有關使用靜態方法初始化多個varibales的想法:
public class SomeClass implements SomeOtherClass{
private String string1= getValues("/var/log/log1.txt");
private String component = getValues("/var/log/log2.txt");
private String getValues(String file) {
try {
return new Scanner(new File(file)).next();
}catch(FileNotFoundException ioe){
System.out.println("File not found :: " +ioe);
}
return null;
}
如果初始化變量可能會失敗,那么它很可能是一個不穩定的候選者。
靜態有利於[有效]不可變,(小心)不可變的緩存和其他很少。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.