异常参数
所有标准异常类都有两个构造器,一个是默认构造器,另一个是接受字符串作为参数,以便能把相关信息放入异常对象的构造器
public class Exception extends Throwable {static final long serialVersionUID = -3387516993124229948L;//构造一个新的异常,将null作为其详细信息。原因没有初始化,可能随后通过调用initCause进行初始化public Exception() {super();}//构造一个具有指定详细信息的新异常。原因没有初始化,可能随后通过调用initCause进行初始化。参数: Message—详细信息。细节消息被保存,以便稍后由getMessage()方法检索public Exception(String message) {super(message);}
能够抛出任意类型的Throwable类型的异常,因为他是异常类型根类。
抛出异常
当发生错误时,例如,用户输入了非法的字符,我们就可以抛出异常。
如何抛出异常?参考Integer.parseInt()方法,抛出异常分两步:
- 创建某个Exception的实例;
- 用throw语句抛出。
实际上我们会把上面的例子写成一行void process2(String s) {if (s==null) {NullPointerException e = new NullPointerException();throw e;}}
如果一个方法捕获了某个异常后,又在catch子句中抛出新的异常,就相当于把抛出的异常类型“转换”了: ```java void process1(String s) { try {void process2(String s) {if (s==null) {throw new NullPointerException();}}
} catch (NullPointerException e) {process2();
} }throw new IllegalArgumentException();
void process2(String s) { if (s==null) { throw new NullPointerException(); } }
当process2()抛出NullPointerException后,被process1()捕获,然后抛出IllegalArgumentException()。如果在main()中捕获IllegalArgumentException,看看打印的异常栈:```javapublic class Main {public static void main(String[] args) {try {process1();} catch (Exception e) {e.printStackTrace();}}static void process1() {try {process2();} catch (NullPointerException e) {throw new IllegalArgumentException();}}static void process2() {throw new NullPointerException();}}java.lang.IllegalArgumentExceptionat Main.process1(Main.java:15)at Main.main(Main.java:5)
这说明新的异常丢失了原始异常信息,我们已经看不到原始异常NullPointerException的信息了。
为了能追踪到完整的异常栈,在构造异常的时候,把原始的Exception实例传进去,新的Exception就可以持有原始Exception信息。对上述代码改进如下:
public class Main {public static void main(String[] args) {try {process1();} catch (Exception e) {e.printStackTrace();}}static void process1() {try {process2();} catch (NullPointerException e) {throw new IllegalArgumentException(e);}}static void process2() {throw new NullPointerException();}}
java.lang.IllegalArgumentException: java.lang.NullPointerExceptionat Main.process1(Main.java:15)at Main.main(Main.java:5)Caused by: java.lang.NullPointerExceptionat Main.process2(Main.java:20)at Main.process1(Main.java:13
注意到Caused by: Xxx,说明捕获的IllegalArgumentException并不是造成问题的根源,根源在于NullPointerException,是在Main.process2()方法抛出的。
在代码中获取原始异常可以使用Throwable.getCause()方法。如果返回null,说明已经是“根异常”了
