3

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

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

public static final Image UP_ARROW;

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

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. 我准备宣布胜利并继续前进。但现在我得到另一个意外的编译器错误:

最后一个字段 UP_ARROW 可能已经被分配

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

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

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

4

2 回答 2

4

以下应该做到这一点:

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将最终分配包含在一个block中可能是有意义的。

于 2012-11-27T22:24:17.013 回答
1

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;
    }
}

这解决了您的问题,并为您提供了enumover static finalvariables 的所有优势。

于 2012-11-27T22:34:49.843 回答