1.异常
根类Throwable体系:
- Error:严重错误,不能处理的问题
- Exception:编译期异常,这种异常是强制我们使用catch捕获处理或throws抛出给调用者。你遇到这种异常必须进行catch或throws,如果不处理,编译器会报错。
- RuntimeExeption:Exception的子类,运行时异常,这种异常我们不需要处理,完全由虚拟机接管。
- NullPointerException:RuntimeExeption的子类,空指针异常
- RuntimeExeption:Exception的子类,运行时异常,这种异常我们不需要处理,完全由虚拟机接管。
异常处理的五个关键字:try,catch,finally,throw,throws
(1)抛出异常 throw:
语法:throw new 异常类名(参数)
例子:throw new NullPointerException(“要访问的数组不存在”)
注意:
- throw关键字必须放在方法的内部
- throw关键字后边new的对象必须是Exception或Exception子类对象
- throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
- throw关键字后边创建的是RuntimeException或RuntimeException的子类对象,我们可以不处理默认交给JVM处理(打印异常对象,中断程序)
- throw关键字后边创建的是编译异常,我们处理这个异常,要么throws,要么try...catch
Objects的非空判断:
Objects.requireNonNull(obj,message),用来判断obj是否为空,为空则抛出异常,信息为message
(2)throws关键字:异常处理的第一种方式,交给别人处理
作用:将异常抛出给方法的调用者处理,最终交给JVM处理-->中断处理
使用格式:在方法声明时使用
修饰符 返回值类型 方法名(参数列表) throws 异常1,异常2...{ throw new 异常1("xxx"); throw new 异常2("xxx"); ... }
注意:
- 必须写在方法声明处
- 声明的异常必须是Exception或Exception子类对象
- 方法内部抛出多个异常,声明处必须也要声明多个异常,如果抛出父异常也抛出子异常则只要声明父异常即可
- 我们必须处理声明的异常
- 要么交给方法调用者处理,最终交给JVM
- 要么使用try...catch自己处理异常
(3)如何获取异常信息
Throwable中定义了一些查看异常的方法:
- public String getMessage():获取异常描述信息
- public string toString():获取异常的类型和异常描述信息
- public void printStackTrace():打印异常的跟踪栈信息并输出到控制台
(4)try,catch,finally
语法:
try{ 可能出现异常的代码 }catch(异常类1 变量名){ 异常处理的逻辑 } ... catch(异常类n 变量名){ }finally{ 无论是否出现异常都会执行 }
注意:
- finally不能单独使用,必须和try一起使用
- finally一般用于资源释放
- 如果finally中有return则永远返回finally中的结果,我们需要避免出现return。
- 当一个catch捕获来处理异常后就不会调用其他catch处理异常了
- 多个catch捕获异常,我们先进行子异常捕获处理,如果没有子异常我们就进行父异常捕获处理
(5)异常注意事项
- 多个异常分别处理:多个try..catch 处理
- 多个异常一次捕获,多次处理:一个try多个catch处理,子异常在前,父异常在后
- 多个异常一次捕获,一次处理:一个try...catch,异常为所有异常的父类或本身
- 子父类异常:
- 如果父类抛出多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常
- 父类方法没有抛出异常,子类重写父类方法时也可不抛出异常,此时子类产生异常,只能捕获异常,不能声明抛出
1 class Father{ 2 public void show01() throws NullPointerException,ClassCastException{} 3 public void show02() throws IndexOutOfBoundsException{} 4 public void show03() throws IndexOutOfBoundsException{} 5 public void show04() {} 6 } 7 8 class Son extends Father{ 9 //子类重写父类方法时,抛出和父类相同的异常 10 public void show01() throws NullPointerException,ClassCastException{} 11 //子类重写父类方法时,抛出父类异常的子类 12 public void show02() throws IndexOutOfBoundsException{} 13 //子类重写父类方法时,不抛出异常 14 public void show03() throws IndexOutOfBoundsException{} 15 //子类重写父类方法时,父类没有抛出异常,子类自己处理异常 16 public void show04() { 17 try { 18 throw new Exception("出现异常"); 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 } 23 }
2.自定义异常类
- 继承Exception处理方式:
- 第一种:抛出异常给调用者,需要声明
- 第二种:自己处理
- 继承RuntimeException处理方式:
- 直接抛出,不用声明直接交给JVM处理
1 public class demo02 { 2 3 4 //抛出异常给调用者处理,需要声明 5 public static void testException1() throws TestException { 6 System.out.println("这是testException1"); 7 throw new TestException("testException1"); 8 } 9 10 11 //抛出异常自己处理 12 public static void testException2() { 13 System.out.println("这是testException2"); 14 try { 15 throw new TestException("testException1"); 16 } catch (TestException e) { 17 e.printStackTrace(); 18 return ; //用于结束方法 19 } 20 21 } 22 23 //运行时异常不用处理和声明,交给JVM处理,最终中断处理 24 public static void testRuntimeException(){ 25 System.out.println("这是testRuntimeException"); 26 throw new TestRuntimeException("testRuntimeException"); 27 } 28 29 public static void main(String[] args) throws TestException { 30 31 demo02.testException1(); 32 demo02.testException2(); 33 demo02.testRuntimeException(); 34 35 } 36 }
TestException
1 public class TestException extends Exception { 2 3 public TestException() { 4 super(); 5 } 6 7 public TestException(String message) { 8 super(message); 9 } 10 }
TestRuntimeException
1 public class TestRuntimeException extends RuntimeException{ 2 3 public TestRuntimeException() { 4 super(); 5 } 6 7 public TestRuntimeException(String message) { 8 super(message); 9 } 10 }