[英]How to handle a static final field initializer that throws checked exception
我正面臨一個用例,我想用聲明為拋出已檢查異常的初始化語句聲明一個static final
字段。 通常,它看起來像這樣:
public static final ObjectName OBJECT_NAME = new ObjectName("foo:type=bar");
我在這里遇到的問題是ObjectName
構造函數可能會拋出各種已檢查的異常,我並不關心(因為我知道我的名字是有效的,如果它不幸崩潰也沒關系,以防萬一)。 java編譯器不會讓我忽略這個(因為它是一個檢查異常),我不想訴諸於:
public static final ObjectName OBJECT_NAME;
static {
try {
OBJECT_NAME = new ObjectName("foo:type=bar");
} catch (final Exception ex) {
throw new RuntimeException("Failed to create ObjectName instance in static block.", ex);
}
}
因為靜態塊真的非常難以閱讀。 有沒有人對如何以一種漂亮、干凈的方式處理這種情況提出建議?
如果您不喜歡靜態塊(有些人不喜歡),那么另一種方法是使用靜態方法。 IIRC,Josh Bloch 推薦了這個(顯然不是在快速檢查的 Effective Java 中)。
public static final ObjectName OBJECT_NAME = createObjectName("foo:type=bar");
private static ObjectName createObjectName(final String name) {
try {
return new ObjectName(name);
} catch (final SomeException exc) {
throw new Error(exc);
}
}
或者:
public static final ObjectName OBJECT_NAME = createObjectName();
private static ObjectName createObjectName() {
try {
return new ObjectName("foo:type=bar");
} catch (final SomeException exc) {
throw new Error(exc);
}
}
(編輯:更正第二個示例以從方法返回而不是分配static
。)
您的代碼完全有效。 我覺得讀起來不難。 其他方式只會讓情況變得更糟。 它們只是初學者難以閱讀,因為他們中的大多數人都不熟悉。 只需遵循有關代碼中元素排序的標准約定。 例如,不要將靜態初始化器放在代碼的中間或整個底部,也不要將它們中的多個散布在整個類中。 只需在靜態聲明之后將一個放在頂部。
static
塊不難閱讀。 所以我推薦這個解決方案。 但是,您可以將您的對象包裝在另一個對象中,例如ObjectNameWrapper
,它與您的ObjectName
共享一個interface
,並且其構造函數調用您的ObjectName
構造函數,隱藏發生的所有已檢查異常。 但同樣,我會選擇靜態選項。
您可以使用用 Lombok 的@SneakyThrows
注釋的方法
public static final ObjectName OBJECT_NAME = createObjectName();
@SneakyThrows(SomeException.class)
private static ObjectName createObjectName() {
return new ObjectName("foo:type=bar");
}
此注釋使受檢查的異常表現得像未經檢查的異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.