起初我只是提出Image
课程的问题,但我想尽可能广泛地适用。
基本上,就是这个场景。我正在为GUI常量制作一个文件,在这个文件中,我想为每个Image
我使用的最终变量。所以我的字段被声明为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
填充。我准备宣布胜利并继续前进。但现在我得到另一个,意外的编译器错误:
...再次挫败,编译!
因此问题:有没有办法解决这个问题,这样我可以在运行时动态加载最终字段?或者我宣布失败并简单地使Image
成为非决赛?
此外,关于编译器为什么不允许这样做的解释也会有所帮助。据我了解,基于上面的代码,UP_ARROW
对象在到达catch{}
块之前无法分配,因为那是什么必须抛出异常。因此,如果try{}
成功执行,则只进行一次分配。如果未成功执行,则仍然只进行一次分配。这怎么没有效?
答案 0 :(得分: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
块中可能是有意义的。
答案 1 :(得分: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;
}
}
这可以解决您的问题,并为您提供enum
超过static final
个变量的所有优势。