所以,我正在尝试在构造函数中初始化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;
}
}
如果这是正确的,或者您有任何其他建议,请告诉我。我很感激帮助!
答案 0 :(得分:11)
是的,在捕获SocketException
之后将其包装在运行时异常中并重新抛出它。由于您的变量是final
并且在对象初始化期间遇到错误,因此您的对象可能处于错误状态,并且您可以保证它将保持不变状态。
记录异常对于异常处理和隐藏来说可能不够SocketException
隐藏了对象无效的事实,并允许您继续冒险,冒NullPointerException
或其他人。
如果你真的想创建这样一个有缺陷的对象,你的建议很好,只需使用另一种方法:
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
...你明白了: - )
P.S。:为什么synchronized
?
P.S.2.2 // Log error
之前的评论logger.error()
没有增加太多价值,你不觉得吗?
答案 1 :(得分:5)
一种可能的替代方法是让你的构造函数抛出SocketException。这将消除对强制您使用临时变量的try-catch块的需要。