为什么这里忽略了catch语句?

Tha*_*son 1 java try-catch stack-trace

这是一本书中的练习代码,我正在学习try/catch语句.

显示的第一种方法要求load方法检索两个图像.此代码中的错误是资源文件中第一个img的名称称为"welcome.png",但正如您所看到的,它显示为"welcomee.png"(欢迎结束时的额外e).当我运行代码时,它不会打印出catch语句中的代码.它确实显示了堆栈跟踪(因为无论如何都会这样做),但它不会打印出"读取时出错:文件名".为什么是这样?

   public class Resources {

    public static BufferedImage welcome, iconimage;

    public static void load() {
        welcome = loadImage("welcomee.png");
        iconimage = loadImage("iconimage.png");
    }

    private static AudioClip loadSound(String filename) {
        URL fileURL = Resources.class.getResource("/resources/" + filename);
        return Applet.newAudioClip(fileURL);
    }

    private static BufferedImage loadImage(String filename) {
        BufferedImage img = null;
        try {
            img = ImageIO.read(Resources.class.getResourceAsStream("/resources/" + filename));
        } catch (IOException e) {
            System.out.println("Error while reading: " + filename);
            e.printStackTrace();
        }
        return img;
    }
}
Run Code Online (Sandbox Code Playgroud)

Boa*_*ann 5

你正在捕捉一个IOException,但如果找不到资源则不会Class.getResourceAsStream抛出IOException; 它只返回null.而且ImageIO.read不会抛出IOException,如果参数为null; 它扔了一个IllegalArgumentException.

我建议你这样重构代码:

private static BufferedImage loadImage(String filename) {
    try (InputStream in = Resources.class.getResourceAsStream("/resources/" + filename)) {
        if (in == null) throw new IOException("Resource not found");
        return ImageIO.read(in);
    } catch (IOException e) {
        System.out.println("Error while reading: " + filename);
        e.printStackTrace();
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将确保您处理错误,并且使用try-with-resources语句可确保在使用后始终关闭流(ImageIO.read但不会这样做).直接return声明可能更清晰,因为它不需要img变量.

您还应该考虑,而不是在出错时返回null,向调用者抛出(或重新抛出)一些异常,例如UncheckedIOException,因为null返回值只会在您尝试使用它时导致其他地方出现错误,并且异常从问题的角度直接NullPointerException抛出将比后来抛出的更有意义.