1.java 中 finally 块一定会执行吗?
答:不一定。如果在try或者catch语句中使用了System.exit(0)语句,那么就不会执行接下来的代码了。因为执行到System.exit(0)时,程序已经被结束了。当然,大部分情况下,在try...catch语句块中都不会有System.exit(0),所以finally会被执行。此外应该注意,避免在finally语句中使用return语句,因为finally语句中的return会把try...catch语句中的return结果给覆盖掉。
2.关于 java 中的异常处理你有啥心得或者经验?
-
方法返回值尽量不要使用 null(特殊场景除外),这样可以避免很多 NullPointerException 异常。
-
catch 住了如果真的没必要处理则至少加行打印,这样可在将来方便排查问题。
-
接口方法抛出的异常尽量保证是运行时异常类型,除非迫不得已才抛出检查类型异常。
-
避免在 finally 中使用 return 语句或者抛出异常,如果调用的其他代码可能抛出异常则应该捕获异常并进行处理,因为 finally 中 return 不仅会覆盖 try 和 catch 内的返回值且还会掩盖 try 和 catch 内的异常,就像异常没有发生一样(特别注意,当 try-finally 中没有 return 时该方法运行会继续抛出异常)。
-
尽量不要在 catch 块中压制异常(即什么也不处理直接 return),因为这样以后无论抛出什么异常都会被忽略,以至没有留下任何问题线索,如果在这一层不知道如何处理异常最好将异常重新抛出由上层决定如何处理异常。
-
方法定义中 throws 后面尽量定义具体的异常列表,不要直接 throws Exception。
-
捕获异常时尽量捕获具体的异常类型而不要直接捕获其父类,这样容易造成混乱。
-
避免在 finally 块中抛出异常,不然第一个异常的调用栈会丢失。
-
不要使用异常控制程序的流程,譬如本应该使用 if 语句进行条件判断的情况下却使用异常处理是非常不好的习惯,会严重影响性能。
-
不要直接捕获 Throwable 类,因为 Error 是 Throwable 类的子类,当应用抛出 Errors 的时候一般都是不可恢复的情况。
3.java 中 Error 和 Exception 有什么区别?
答:Error 表示系统级的错误,是 java 运行环境内部错误或者硬件问题,不能指望程序来处理这样的问题,除了退出运行外别无选择,它是 java 虚拟机抛出的。Exception 表示程序需要捕捉、需要处理的异常,是由与程序设计的不完善而出现的问题,程序可以处理的问题。
4.java 中被检查的异常(即编译时异常)和不受检查的异常(运行时异常)有什么区别?
答:被检查的异常应该用 try-catch 块代码处理或用 throws 关键字抛出,不受检查的异常在程序中不要求被处理或用 throws 抛出;Exception 是所有被检查异常的基类,而 RuntimeException(是 Exception 的子类) 是所有不受检查异常的基类;被检查的异常适用于那些不是因程序引起的错误情况(如 FileNotFoundException),而不被检查的异常通常都是由于糟糕的编程引起(如 NullPointerException)。
5. java 中 throw 与 throws 的区别是什么?
答:二者都是抛出异常的关键字,区别:
throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行
throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)