讓我們說我有下面的類Java實例成員初始化拋出異常
public class A {
private B b;
}
現在有一個工廠,用於創建B的實例,但創作者方法拋出一個異常
public class BCreatorFactory {
public static createB() throws SomeException {
// DO the intialization
// ...
return b;
}
如果我在聲明行中設置Ab,那麼我將無法處理異常
public class A {
private B b = BCreatorFactory.createB() // BAD -> no way of dealing with the exception
}
,如果我在構造函數中設置的Ab那麼我要麼有一個「半出爐的」實例或者我再次拋出一個異常,並強制調用代碼來處理不正確初始化實例
public class A {
private B b;
public A() {
try {
b = BCreatorFactory.createB();
}
catch (SomeException se) {
// Do something, perhaps try to recover ? <- IMO also BAD
}
}
}
或
public class A {
private B b;
public A() throws SomeException { // BAD
b = BCreatorFactory.createB();
}
}
我可以嘗試延遲初始化B的實例:
public class A {
private B b;
public B getB() throws SomeException {
if (b == null) {
b = BCreatorFactory.createB(); // BAD -> not thread safe -> can result in redundant createB() invocations
}
return b;
}
}
但我能想到使它線程安全的唯一方法是通過的已知的Java的JVM中內破雙重檢查鎖定
public class A {
private B b;
public B getB() throws SomeException {
if (b == null) {
synchronized(this) {
if (b == null) {
b = BCreatorFactory.createB(); // BAD -> not really thread safe -> broken
}
}
}
return b;
}
}
那麼,什麼,親愛的讀者病人,應該怎麼辦?
換句話說,什麼是初始化一個對象實例的最佳解決方案,該實例包含對創建可能會引發異常的對象的引用?
我不清楚爲什麼你認爲讓A的構造函數拋出'SomeException'是一件壞事。 –
爲什麼你認爲拋出B的異常是不好的? –
當拋出異常時你期望發生什麼?如果不知道這個,很難知道該怎麼做。 –