使用引发异常的方法在静态块中初始化的最终静态变量



请考虑以下部分代码

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;

最新更新