[英]Why assigning a final field in a try-catch block within a static block is rejected?
[英]Assigning a final field in a try-catch block within a constructor
所以,我試圖在構造函數中初始化一個DatagramSocket
,我希望這個字段是final
,但是我的編譯器(即 Eclipse )給了我以下錯誤:
空白的最終字段 datagramSocket 可能尚未初始化
這是可以理解的。 這是一個代碼片段:
public class Foo
{
private final int DEFAULT_UDPLISTENPORT = 49400;
private final DatagramSocket datagramSocket;
public Foo()
{
synchronized(this)
{
try
{
datagramSocket = new DatagramSocket(DEFAULT_UDPLISTENPORT);
}
catch (SocketException e)
{
// Log error
logger.error("Trouble opening UDP port: ", e);
}
}
}
}
現在,我知道有一種方法可以繞過它,但它需要我創建一個臨時變量。 這是一個代碼片段:
public class Foo
{
private final int DEFAULT_UDPLISTENPORT = 49400;
private final DatagramSocket datagramSocket;
public Foo()
{
synchronized(this)
{
DatagramSocket tempSocket = null;
try
{
tempSocket = new DatagramSocket(DEFAULT_UDPLISTENPORT);
}
catch (SocketException e)
{
// Log error
logger.error("Trouble opening UDP port: ", e);
}
datagramSocket = tempSocket;
}
}
}
所以,我想我的問題是:有沒有更優雅的方式來做到這一點,或者如果我想讓那個領域成為final
的,我就必須忍受這種方式?
編輯:
對於那些感興趣的人,這是我根據您的建議提出的解決方案:
public class Foo
{
private static final Foo INSTANCE;
static
{
try
{
INSTANCE = new Foo();
}
catch (SocketException e)
{
throw new ExceptionInInitializerError(e);
}
}
private final int DEFAULT_UDPLISTENPORT = 49400;
private final DatagramSocket datagramSocket;
public Foo() throws SocketException
{
synchronized (this)
{
datagramSocket = new DatagramSocket(DEFAULT_UDPLISTENPORT);
}
}
public static Foo getInstance()
{
return INSTANCE;
}
}
請讓我知道這是否正確,或者如果您有任何其他建議。 感謝您的幫助!
是的,在捕獲SocketException
后將其包裝在運行時異常中並重新拋出它。 由於您的變量是final
變量,並且您在 object 初始化期間遇到錯誤,因此您的 object 可能是不正確的 state 並且您可以保證它會保持原樣。
記錄異常可能不足以進行異常處理和隱藏SocketException
隱藏了 object 無效的事實,並允許您繼續,冒着NullPointerException
或其他風險。
如果你真的想制造這樣一個故障的object,你的建議沒問題,換一種方法就好了:
public Foo()
{
synchronized(this)
{
datagramSocket = createSocket();
}
}
private DatagramSocket createSocket() {
try
{
return new DatagramSocket(DEFAULT_UDPLISTENPORT);
}
catch (SocketException e)
{
logger.error("Trouble opening UDP port: ", e);
return null; //I beg you, don't return null here...
}
}
至於返回null
:考慮繼承DatagramSocket
並創建:
NoOpDatagramSocket
NullDatagramSocket
BrokenDatagramSocket
MemoryDatagramSocket
...你明白了:-)
PS:為什么要synchronized
?
PS2:在logger.error()
之前的注釋// Log error
並沒有增加太多價值,你不覺得嗎?
一種可能的替代方法是讓您的構造函數拋出 SocketException。 這將消除強制您使用臨時變量的 try-catch 塊的需要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.