1.你可以catch多个exceptions,如果有几个要做的操作一样,你甚至可以把他们写在一个里面,这样不仅好看而且运行还会变快,但是这样这个参数e就会变成final了,你就不能在catch里改动他了。那这多个可以有superclass/subclass关系吗
try
{
code that might throw exceptions
}
catch (FileNotFoundException | UnknownHostException e)
{
emergency action for missing files and unknown hosts
}
2.你可以重新丢出异常,最好可以把他的cause也写上
try
{
access the database
}
catch (SQLException original)
{
var e = new ServletException("database error");
e.initCause(original);
throw e;
}
3.try-catch-finally的一些问题
var in = new FileInputStream(. . .);
try
{
// 1
code that might throw exceptions
// 2
}
catch (IOException e){
// 3
show error message
// 4
}
finally
{
// 5
in.close();
}
// 6
分析一下情况
(1)try里抛出了异常,被catch接住了,没有再次抛出,那么会执行1,3,4,5,6
如果再次抛出了,那么会执行1,3,5
(2)try里抛出了异常,catch没接住,那么会执行1,5
(3)try里没抛出异常,那么就会执行1,2,5,6
4.finally里不要写return之类的,因为他是最后执行的,会导致一些奇怪的问题
5.因为finally里也可能出问题,所以最好是写两个嵌套的try,分别处理正常的异常和finally里的异常
InputStream in = . . .;
try
{
try
{
code that might throw exceptions
}
finally
{
in.close();
}
}
catch (IOException e)
{
show error message
}
不过其实没必要,因为不要用finally,用下面提到的try-with
6.可以不写catch,上面那个就是个例子
7.有些类执行了AutoCloseable接口,这样就可以不用写finally然后关闭了,因为它会自动关掉,你甚至可以同时try两个文件,他们最后都会自动关掉。而且,如果try里的和close里都抛出异常了,这个try-with会优雅的处理,他会抛出原异常,并且把close里的异常捕捉并加到原异常里。try-with也可以写catch和finally,他们在close之后执行。那用不用catch呢,在方法前面声名不声明throws exception有区别吗
try (var in = new Scanner(Path.of("in.txt"),
StandardCharsets.UTF_8);
var out = new PrintWriter("out.txt",
StandardCharsets.UTF_8))
{
while (in.hasNext())
out.println(in.next().toUpperCase());
}
8.不要被异常处理蒙蔽了双眼,因为catch很花时间,用些简单的判空就不要catch了。
9.不要把每一句代码都套上一个try-catch,完全可以给一大块代码套一个try-catch,因为异常处理的本意是把正常的代码过程和错误处理分开来。
10.尽可能把异常细化,别净写些假大空的异常。
11.不要说有些异常一万年出一次你就不抛出,然后用一个什么都不干的catch来消除他,这样做会导致很严重的后果,你如果嫌给调用它的每一个方法后面写throws麻烦,你就老老实实认真的把这个异常catch了。
12.有些你处理不了的异常你就别管了,高级的方法会有他的办法的,你就传下去就好了。
13.用标准的方法来报告null-pointer and out-of-bounds exceptions
requireNonNull
checkIndex
checkFromToIndex
checkFromIndexSize
注意这些异常都是unchecked的,所以不用在你的方法里声明异常,也不用catch