考虑以下部分代码
private static class InnerClass
{
private static final BufferedImage connectionImage; // line A
private static final int width;
// other not relevant fields
static
{
try
{
connectionImage = ImageIo.read(...); // doeasn't really matter - any method that throws exception
}
catch(IOException e)
{
// handle
connectionImage = null; // line B
}
if(connectionimage != null) // line C
{
width = connectionImage.getWidth();
}
else
{
width =0;
}
}
// rest of the class definition
}
我在这种情况下我在B行上得到“变量可能已被分配”,如果我在try{}
块中有更多行并且在我的变量初始化之后导致异常,则可能是真的。当我从A行删除单词final
时,它编译正常,但是当我尝试使用static {}
分配imageWidth / height(也是最终静态)时,我会在connectionImage.getWidth()
块中收到警告(当然,如果它不是空的)。警告是“在初始化期间使用非最终变量”。如果我决定在A行中使用final
并删除B行,我会在C行收到“变量connectionImage可能尚未初始化”。
我的问题是:有没有办法在static {}
块中使用抛出异常的函数(或者通常在try/catch
内)初始化和使用静态最终变量,或者我应该处理其他方式? (构造)
注意(如果相关): 是的,这个类的名字是告诉你它是内部类。它也是静态的,因为如果不是,我不能在里面声明静态字段。
我知道如何编写代码来完成我不会做的事情,但是我想拥有这个内部类,因为我的方便和分离一些行为。我只是不知道静态最终,静态块,尝试/捕获情况。我在谷歌找不到这方面的好消息,我甚至检查了我的旧'在Java中的思考'......
这是类似的Java - Can final variables be initialized in static initialization block?,但是作者没有尝试初始化catch中的变量,也没有在赋值后在静态块中使用它们,所以他没有得到“非最终的使用... “稍后警告。
答案 0 :(得分:3)
基本上,您应该使用局部变量:
BufferedImage localImage = null;
try
{
localImage = ImageIo.read(...);
}
catch (IOException e)
{
// No need to set a value, given that it's already going to be null.
// You probably want to log though.
}
connectionImage = localImage;
现在您确定您的connectionImage
变量将只分配一次。
然后我会使用width
的条件运算符,这使得更清楚的是只有一个赋值:
width = connectionImage != null ? connectionImage.getWidth() : 0;