为什么 catch 语句在这里被忽略了?
Why is the catch statement being ignored here?
这是一本书中的练习代码,我正在学习 try/catch 语句。
显示的第一个方法调用加载方法并检索两个图像。此代码中的错误是资源文件中第一个 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;
}
}
您正在捕获 IOException
,但如果参数为空,Class.getResourceAsStream
doesn't throw an IOException
if the resource is not found; it just returns null. And ImageIO.read
不会抛出 IOException
;它抛出一个 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;
}
}
这将确保您处理错误,并且使用 try-with-resources 语句可确保流在使用后始终关闭(ImageIO.read
不会)。直接 return
语句可能更简洁一些,因为它避免了对 img
变量的需要。
您还应该考虑向调用者抛出(或重新抛出)一些异常,例如 UncheckedIOException
,而不是在出错时 returning null,因为 null return 值只会在您尝试使用它时在其他地方引起错误,并且直接从问题点抛出的异常将比稍后抛出的一些 NullPointerException
更有意义。
你只能抓到IOException
。如果要捕获所有类型的异常,请使用 catch(Exception e)
.
请尝试使用 catch(Exception e){...}
。这是一种检查它是否只是另一个异常或者它是否不是异常而是 运行 时间错误的方法。
如果需要,您可以在开发过程的后期指定特定的 catch 语句和特定的异常。
这是一本书中的练习代码,我正在学习 try/catch 语句。
显示的第一个方法调用加载方法并检索两个图像。此代码中的错误是资源文件中第一个 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;
}
}
您正在捕获 IOException
,但如果参数为空,Class.getResourceAsStream
doesn't throw an IOException
if the resource is not found; it just returns null. And ImageIO.read
不会抛出 IOException
;它抛出一个 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;
}
}
这将确保您处理错误,并且使用 try-with-resources 语句可确保流在使用后始终关闭(ImageIO.read
不会)。直接 return
语句可能更简洁一些,因为它避免了对 img
变量的需要。
您还应该考虑向调用者抛出(或重新抛出)一些异常,例如 UncheckedIOException
,而不是在出错时 returning null,因为 null return 值只会在您尝试使用它时在其他地方引起错误,并且直接从问题点抛出的异常将比稍后抛出的一些 NullPointerException
更有意义。
你只能抓到IOException
。如果要捕获所有类型的异常,请使用 catch(Exception e)
.
请尝试使用 catch(Exception e){...}
。这是一种检查它是否只是另一个异常或者它是否不是异常而是 运行 时间错误的方法。
如果需要,您可以在开发过程的后期指定特定的 catch 语句和特定的异常。