gpt4 book ai didi

java - 在构造函数中的 try-catch block 中分配最终字段

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:06:28 25 4
gpt4 key购买 nike

所以,我试图在构造函数中初始化一个 DatagramSocket,我希望这个字段是 final,但是我的编译器(即 Eclipse)给了我以下错误:

The blank final field datagramSocket may not have been initialized

这是可以理解的。这是一个代码片段:

    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 并且您在对象初始化期间遇到错误,您的对象可能处于不正确的状态并且您保证它将保持原样。

记录异常可能不足以进行异常处理,隐藏 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.2:logger.error() 之前的注释 //Log error 没有增加太多值(value),你不觉得吗?

关于java - 在构造函数中的 try-catch block 中分配最终字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5858250/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com