异常(Exception)
异常主要分为运行时异常、非运行时异常(编译时异常)。
一、运行时异常(RuntimeException)
运行时异常又叫未检查异常、非受控异常,发生概率小,运行时异常和错误(Error)都属于编译器不强制要求处理的异常。运行时异常包括RuntimeException类及其子类异常,所以当我写了一个异常继承自运行时异常直接继承RuntimeException类及其子类异常。
二、非运行时异常(编译时异常)
编译时异常又叫受检异常、受控异常,一旦出现编译器会强制要求进行处理。编译时异常是除了RuntimeException类的Exception类及其子类的所有异常,所以当我写了一个异常继承自非运行时异常直接继承Exception类及其子类异常。
三、异常与错误的关系(Exception&Error)
举个例子,当一个人已经感冒了这就相当于错误是已经发生的,但一个人出现感冒的症状如咳嗽、头晕等但体温还没到感冒的程度这就相当于异常是可以通过提前吃药或者其他方式防止感冒,然而通过一系列措施防止感冒就相当异常的处理。对一个程序来说异常是可接受的但错误是糟糕的。
四、异常中的一些方法
getMessage();打印构造方法中的参数
printStackTrace();打印异常的详细信息,包括构造方法中的参数
package com.wgj.ExceotionTest;
public class Test {
public static void main(String[] args) {
MyException myException = new MyException("我的自定义异常");
System.out.println(myException.getMessage());
System.out.println();
myException.printStackTrace();
}
}
package com.wgj.ExceotionTest;
public class MyException extends Exception{
public MyException(String message) {
super(message);
}
public MyException() {
super();
}
}
运行结果如下:
我的自定义异常
com.wgj.ExceotionTest.MyException: 我的自定义异常
at com.wgj.ExceotionTest.Test.main(Test.java:5)
五、异常处理
完整的异常捕获是try-catch-finally语句执行的。
异常在发生时其后的语句都不能执行但有时我们想不影响后面的代码就可以把后面的代码放到finally中,不论try中发生了什么finally中的代码是一定会执行的。
如下:
package com.wgj.ExceotionTest;
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 0;
try {
int div=a/b;
System.out.println(div);
}catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("11111111111111");
}
}
}
/*
运行结果如下:
java.lang.ArithmeticException: / by zero
at com.wgj.ExceotionTest.Test.main(Test.java:12)
11111111111111
*/
finally语句一定要与try相连但try可以没有fianlly。catch代码块可以有多个但当try中一旦有一个异常被catch了那么后面就算有异常也只会对第一个被捕获的异常进行处理。
package com.wgj.ExceotionTest;
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 0;
String s=null;
try {
int div=a/b;//ArithmeticException
System.out.println(div);
System.out.println(s.toString());//NullPointerException
} catch (NullPointerException ne) {
ne.printStackTrace();
} catch (ArithmeticException ae) {
ae.printStackTrace();
} finally {
// System.out.println("11111111111111");
}
}
}
/*
运行结果如下:
java.lang.ArithmeticException: / by zero
at com.wgj.ExceotionTest.Test.main(Test.java:14)
*/
其实对异常的处理的线程和main线程是两条线程的。
六、异常抛出
通常我们不知道如何处理捕获的异常时,用throws声明将此异常再次抛出,交给当前方法的上一级调用者,如果上一级也不知道如何处理就会一直往上抛出异常,直到抛给JVM,JVM是就会打印异常的信息跟踪栈,并且将程序结束。对于自定义异常的抛出往往使用throw语句,它抛出的是一个具体的异常对象不是抛出类,每次只能抛出一个对象,一旦执行throw语句后,其后代码都不会执行。