共计 3152 个字符,预计需要花费 8 分钟才能阅读完成。
封面:洛小汐
译者:潘潘
知彼知己,方能百战不殆。
前言
本文总结了无关 Java 异样的十大常见问题。
目录
- 查看型异样(checked)vs. 非查看型异样(Unchecked)
- 异样治理的最佳实际箴言
- 为什么在 try 代码块中申明的变量不能在 catch 或者 finally 中被援用?
- 为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异样不一样呢?
- Java 中常常应用的运行时异样
- 咱们能够在同一个 catch 子句中捕捉多个异样吗?
- 在 Java 中构造方法能抛出异样吗?
- 在 final 代码块中抛出异样
- try 语句有 return 那么 finally 还会执行吗?
- 为何有些开发人员对异样束之高阁?
查看型异样(checked)vs. 非查看型异样(Unchecked)
简略来说,对于查看型异样,个别在 编译期 就会被查看到,所以咱们必定会提前在办法内进行捕捉解决,或者在办法头部申明并抛出。而非查看型异样,往往无奈提前预知,例如被除数是 0、空指针等。查看型异样特地重要,它会通知那些调用你的接口的开发者们,如何提前预知并解决好这些可能产生的异样。
例如,IOException 就是常见的查看型异样,而 RuntimeException(运行时异样)就是非查看型异样。在浏览残余局部之前你或者能够研读这份 Java 异样的层次结构图。
异样治理的最佳实际箴言
如果能够正确处理异样,则应将其捕捉并解决,否则应将其抛出。
为什么在 try 代码块中申明的变量不能在 catch 或者 finally 中被援用?
看上面这段代码,在 try 代码块中申明的 String s 就不能在 catch 中被援用,这段代码在编译期是通不过的。
try {File file = new File("path");
FileInputStream fis = new FileInputStream(file);
String s = "inside";
} catch (FileNotFoundException e) {e.printStackTrace();
System.out.println(s);
}
起因是你不晓得在 try 代码块中哪个地位会引发异样,很有可能在申明对象之前就引发了异样。对于这个特定的示例,是正确的。
为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异样不一样呢?
它俩抛出的异样的确不同,但这是 JDK 的问题,过后开发这两个接口的开发人员不是同一波,所以咱们没必要去纠结这个问题。
Integer.parseInt(null);
// throws java.lang.NumberFormatException: null
Double.parseDouble(null);
// throws java.lang.NullPointerException
Java 中常常应用的运行时异样
这里列举一部分:
IllegalArgumentException
ArrayIndexOutOfBoundsException
在有些场景某个指标对象不满足咱们的预期,会用到这些异样,例如上面在 if 判断语句中被应用:
if (obj == null) {throw new IllegalArgumentException("obj can not be null");
咱们能够在同一个 catch 子句中捕捉多个异样吗?
答案是当然能够,不过如果在同一个 catch 子句中捕捉的这些异样都间接或间接继承自同一父类,那么就只能在 catch 子句中捕捉父类了。
// Java 7 之前须要这样
catch (AException a) {logger.error(a);
throw new MyException("a");
catch (BException b) {logger.error(b);
throw new MyException("b");
}catch (CException c) {logger.error(c);
throw new MyException("c");
}
// 在 Java 7 中,能够捕捉所有这些异样
catch(AException | BException | CException ex){logger.error(ex);
throw new MyException(ex);
}
补充阐明 : 其实是这样,在 Java7 就开始反对 catch 子句捕捉多个异样,多个异样应用 XOR 符号(I)连贯,异样的产生有可能是 A | B,但不能同时呈现,相当于这些异样不能是间接或间接继承自同一个父类,因为如果 AB 都继承同一父类,那就不能 A|B 都写上,这也是继承准则。
在 Java 中构造方法能抛出异样吗?
答案是当然能够,构造方法仅是一种非凡办法而已。能够参考这个示例。
在 final 代码块中抛出异样
上面这个写法是非法的:
public static void main(String[] args) {File file1 = new File("path1");
File file2 = new File("path2");
try {FileInputStream fis = new FileInputStream(file1);
} catch (FileNotFoundException e) {e.printStackTrace();
} finally {
try {FileInputStream fis = new FileInputStream(file2);
} catch (FileNotFoundException e) {e.printStackTrace();
}
}
}
然而为了取得更好的代码可读性,你应该将把 try-catch 代码块封装成一个新办法,而后将办法调用放在 finally 子句中:
public static void main(String[] args) {File file1 = new File("path1");
File file2 = new File("path2");
try {FileInputStream fis = new FileInputStream(file1);
} catch (FileNotFoundException e) {e.printStackTrace();
} finally {
// 封装办法
methodThrowException();}
}
try 语句有 return 那么 finally 还会执行吗?
答案是必定会执行。
Java 官网文档形容:The finally block always executes when the try block exits
意思就是”只有存在 try 代码块,finally 代码块就肯定会执行”,这种个性能够让程序员防止在 try 语句中应用 return, continue 或者 break 关键字而疏忽了敞开相干资源的操作等。
为何有些开发人员对异样束之高阁?
很多时候会见到上面这种代码写法。容许的状况下尽可能捕捉异样并且进行解决,不晓得为什么很多开发人员就是这么干?
try {...} catch(Exception e) {e.printStackTrace();
}
疏忽异样是一件很容易做到的事,尽管这种写法很常见,但不肯定是正确的写法。
参考文献:
- Unchecked exceptions in Java
- The root of Java exception class hierarchy
- Java exceptions related questions in stackoverflow
译文完,因为集体理解能力和常识宽度无限,译文中存在失误之处,还请见谅,欢送斧正。
BIU ~ 文章继续更新,微信搜寻「潘潘和他的敌人们」第一工夫浏览,随时有惊喜。本文会在 GitHub https://github.com/JavaWorld 收录,热腾腾的技术、框架、面经、解决方案,咱们都会以最美的姿态第一工夫送达,欢送 Star。