try catch在编码过程中经常使用,为了捕获可预见的异常,保证程序继续运行。
如果遇到循环处理逻辑,try catch应该放在循环内、还是循环外呢?
我这里记录一下:
通常的一种说法:
try catch放在循环内,异常自己捕获处理。其他循环可以继续执行。
放在循环外,循环体就视为一个整体,一旦发生异常,就不执行。
// 放在外部
try {
for(int i=1;i<4;i++){
int num = 1/0;
System.out.println("i="+i);
}
System.out.println("try");
}catch (ArithmeticException ex){
System.err.println("java.lang.ArithmeticException: / by zero");
}
System.out.println("go");
执行结果:直接报错,跳出try块。继续运行下面的代码。
// 放在内部
for(int i=1;i<4;i++){
try {
int num = 1/0;
System.out.println("try");
}catch (ArithmeticException ex){
System.err.println("java.lang.ArithmeticException: / by zero");
}
System.out.println("i="+i);
}
System.out.println("go");
执行结果:
由于异常被捕获,会抛出异常。跳出try块。循环体内代码继续执行。
扫描二维码关注公众号,回复:
4242917 查看本文章
好戏才刚开始~
// 放在内部
for(int i=1;i<4;i++){
try {
File file = new File("D://test"+i);
FileUtils.cleanDirectory(file);
System.out.println("try");
} catch (IOException e) {
System.err.println("IOException"+i);
}
System.out.println("i="+i);
}
我的D盘,创建了一个test1、test3文件夹。
按照刚才的逻辑,虽然没有test2文件夹,会导致报错。但循环会继续执行。
执行结果:
Why?? 说好的循环内部try catch继续执行呢!
观察错误,发现异常其实未被程序捕获,我们被表象迷惑了!!
让我们看看源码:
/**
* Cleans a directory without deleting it.
*
* @param directory directory to clean
* @throws IOException in case cleaning is unsuccessful
* @throws IllegalArgumentException if {@code directory} does not exist or is not a directory
*/
public static void cleanDirectory(final File directory) throws IOException {
final File[] files = verifiedListFiles(directory);
IOException exception = null;
for (final File file : files) {
try {
forceDelete(file);
} catch (final IOException ioe) {
exception = ioe;
}
}
if (null != exception) {
throw exception;
}
}
虽然这个清空目录文件的方法,抛出的是IOException异常,我们catch也处理了。
但是它还主动抛出了其他的异常!!比如这里的运行时异常:IllegalArgumentException
/**
* Lists files in a directory, asserting that the supplied directory satisfies exists and is a directory
* @param directory The directory to list
* @return The files in the directory, never null.
* @throws IOException if an I/O error occurs
*/
private static File[] verifiedListFiles(File directory) throws IOException {
if (!directory.exists()) {
final String message = directory + " does not exist";
throw new IllegalArgumentException(message);
}
if (!directory.isDirectory()) {
final String message = directory + " is not a directory";
throw new IllegalArgumentException(message);
}
final File[] files = directory.listFiles();
if (files == null) { // null if security restricted
throw new IOException("Failed to list contents of " + directory);
}
return files;
}
于是我们将代码改为:
// 放在内部
for(int i=1;i<4;i++){
try {
File file = new File("D://test"+i);
FileUtils.cleanDirectory(file);
System.out.println("try");
} catch (IOException e) {
System.err.println("IOException"+i);
} catch (IllegalArgumentException e){
System.err.println("IllegalArgumentException"+i);
}
System.out.println("i="+i);
}
执行结果: 虽然报错,但循环继续执行了。
提示:(更加粗暴的方式,就是直接抛出Exception错误,妥妥的都能捕获。运行时异常也是继承Exception的。)
END O(∩_∩)O