【问题标题】:Can an object dynamically loaded with possible exceptions be declared as final?可以将带有可能异常的动态加载的对象声明为最终对象吗?
【发布时间】:2012-11-15 15:57:22
【问题描述】:

起初我只想提出关于 Image 类的问题,但我想让它尽可能广泛地适用。

基本上,这是场景。我正在为 GUI 常量制作一个文件,在这个文件中,我想为我正在使用的每个 Images 提供最终变量。所以我的字段是这样声明的 UP_ARROW 是:

public static final Image UP_ARROW;

然后我尝试在ImageIO API 时加载它们,如下所示:

static {
    UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
}

不幸的是,这不是有效的可编译代码,因为它显式地throws IOException,我必须处理它。所以我修改它并用 try/catch 包围它:

static {
    try {
        UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
    }
    catch(IOException ioe) {
        //TODO
    }
}

现在我得到一个不同的编译器错误。这次它表示该字段可能尚未初始化。好吧,这是有道理的。感谢您向我指出这一点,编译器。这似乎很容易解决:

static {
    try {
        UP_ARROW = ImageIO.read(new File("img/upArrow.png"));
    }
    catch(IOException ioe) {
        UP_ARROW = null;
    }
}

现在,无论如何,UP_ARROW 必须填充我的图像或null。我准备宣布胜利并继续前进。但现在我得到另一个,意外的编译器错误:

... 再次失败,编译器!

因此问题是:有没有办法解决这个问题,以便我可以在运行时动态加载最终字段?还是我宣布失败并简单地将Images 设为非决赛?

另外,解释一下为什么编译器不允许这样做也会很有帮助。据我了解,根据上面的代码,UP_ARROW 对象无法在到达 catch{} 块之前被分配,因为这肯定是引发异常的原因。因此,如果try{} 成功执行,则只发生一次分配。如果它没有成功执行,仍然只有一个分配发生。怎么会无效?

【问题讨论】:

    标签: java variables dynamic exception-handling final


    【解决方案1】:

    以下应该这样做:

    static {
        Image up_arrow = null;
        try {
            up_arrow = ImageIO.read(new File("img/upArrow.png"));
        }
        catch(IOException ioe) {
            // log the error?
        }
        UP_ARROW = up_arrow;
    }
    

    将最终分配包含在 finally 块中可能是有意义的。

    【讨论】:

      【解决方案2】:

      NPE 的回答很好,但我认为这个(基于他的和)更好:

      public enum Arrows {
          UP ("img/upArrow.png"),
          DOWN ("img/downArrow.png"),
          LEFT ("img/leftArrow.png"),
          RIGHT ("img/rightArrow.png");
      
          public final Image myImage;
      
          private Arrows(String fileName) {
              Image tempImage;
              try {
                  tempImage = ImageIO.read(new File(fileName));
              } catch (IOException e) {
                  tempImage = null;
              }
              myImage = tempImage;
          }
      }
      

      这解决了您的问题,并为您提供了 enum 相对于 static final 变量的所有优势。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多