请考虑以下部分代码
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
时,它可以编译正常,但是当我尝试使用 connectionImage.getWidth()
分配 imageWidth/height(也是最终静态(时static {}
块稍后收到警告(当然,如果它不为空(。警告是"初始化期间使用非最终变量"。如果我决定在 A 行中使用 final
并删除 B 行,我会在 C 行得到"变量连接图像可能尚未初始化"。
我的问题是:有没有办法使用抛出异常(或通常在try/catch
内部(的函数将静态最终变量初始化并可在static {}
块中使用,或者我应该以其他方式处理?(构造函数(
注(如果相关(:是的,这个类的名字是告诉你它是内部类。它也是静态的,因为如果不是,我就无法在里面声明静态字段。
我知道如何编写代码来做我不想做的事情,但是由于我的方便,我希望拥有这个内部类并分离一些行为。我只是想知道静态决赛,静态块,尝试/捕获情况。我在谷歌中找不到很好的解释,我什至检查了我的旧"Java 中的Thhinking"......
这是类似 Java 的东西 - 最终变量可以在静态初始化块中初始化吗? 但是作者没有尝试在 catch 中初始化变量,而且他在赋值后也没有在静态块中使用它们,所以他没有得到"非最终的使用..."稍后警告。
基本上,你应该使用局部变量:
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;