异常体系

在Java中,每个异常都是一个对象,其中java.lang.Throwable是所有异常的父类
而Throwable有两个重要的子类:Exception(异常)和Error(错误)
Error:
是程序无法处理的错误,表示运行应用程序中较严重问题
大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题
Exception:
其中Exception时程序本身可以捕获且可以处理的异常,主要分为两类,即运行时异常和编译时异常
运行时异常是非检查性异常,一般都是程序逻辑错误引起的
比如NullPointerException空指针异常,ArrayIndexOutOfBoundsException数组索引越界异常等等
这些异常都可以选择在程序中进行捕获,当然也可以不处理
而编译时异常是检查性异常,是除了RuntimeException及其子类以外的异常
如果程序中出现了此类异常,比如IOExceprion,就表明需要程序员必须对该异常进行处理,否则编译不通过

Exception异常

异常还有很多子类
比如RuntimeException(运行时异常 或 非检查异常)、IOException…..等等

异常分为两种
1 运行时异常(非检查异常)
Error和RuntimeException都算做运行时异常
javac编译时 不会被提示和发现
在程序编写时不要求必须做处理 如果我们愿意可以添加处理手段(try throws)
我们需要知道 出现这类异常时 怎么去修改
2 编译时异常(检查异常)
除了Error和RuntimeException以外的异常
javac编译时 强制要求我们必须处理这些异常(try 或 throws)
因为这样的异常在程序运行的过程中极有可能产生问题
异常产生后 后续的所有执行就停止了

添加处理异常的手段
处理异常不是异常消失了
处理异常指的是 处理掉异常后 后续的代码不会因为此异常而中止执行

两种手段
1. try{}catch(){}[finally{}]
1.1 try不能单独出现 后面必须添加 catch(捕获异常的名字) 或 finally
1.2 catch()内是为了捕获我们指定的异常 如 catch(NullPointerException e)
1.3 catch可以有多个存在 每一个负责捕获一种异常
捕获的异常之间没有任何继承关系
捕获的异常需要从小到大进行捕获

String s = “abc”;
try{
char c = s.charAt(10);
}catch (StringIndexOutOfBoundsException e){
System.out.println(“捕获到了字符串越界异常”);
}catch (Exception e){//Exception所有异常的父类
System.out.println(“捕获到了异常”);
}
1.4 finally后面没有括号 不是必须存在
若存在finally结构 则必须执行
String s = “abc”;
try{
char c = s.charAt(10);
}finally {
System.out.println(“我必须执行”);
}
//就算出现了异常 也必须执行
//输出 我必须执行
*1.5 (笔试)处理异常如果放在方法内部 可能会有小问题
如果在方法内部有返回值 不管return放在那里 finally都会执行
如:

  1. public String testException(){
  2. try{
  3. System.out.println("try开始执行了");
  4. String str = null;
  5. //str.length();//空指针异常
  6. System.out.println("try执行完毕");
  7. return "try的返回值";//注意 try catch finally是一个整体
  8. //整体执行完才会执行return 所以就算return在try中执行了 输出时也会在finally执行完后 才会返回
  9. //即如果没有出现异常 返回值就是 try的返回值
  10. //出现异常后 就返回的是 最终返回值
  11. }catch (Exception e){
  12. e.printStackTrace();//如果不知道异常是什么 可以用这个方法来打印输出异常
  13. System.out.println("捕获到了异常");
  14. } finally {
  15. System.out.println("finally必须执行");
  16. }
  17. return "最终返回值";
  18. }
  19. public static void main(String[] args) {
  20. Test t = new Test();
  21. System.out.println(t.testException());
  22. }

2.throws 抛出
2.1 异常只能在方法结构上抛出 属性是不能处理异常的
2.2 方法 构造都可以抛出异常
2.3 方法可以抛出不止一个异常 可以抛出多个 抛出 异常间用 ,隔开
2.4 抛出的异常 要么没关系 要么先抛出小异常 即由小到大
2.5 谁调用此方法 谁处理异常
2.6 若抛出的是 throws Exception 相当于默认我们没写 程序执行后 如果我们没有捕获这个异常 系统会提示我们要对异常进行捕获
如:

  1. public Test() throws NullPointerException{
  2. //构造方法也能抛出异常
  3. }
  4. public String testException() throws Exception{
  5. String str = null;
  6. str.charAt(10);
  7. str.length();
  8. return "最终返回值";
  9. }
  10. public static void main(String[] args) {//主方法也可以抛出异常 但是通常不这么做 因为异常只能抛给虚拟机了 都没人处理
  11. Test t = new Test();
  12. try {
  13. t.testException();
  14. }catch (Exception e){
  15. System.out.println("捕获了异常");
  16. }
  17. }