Java try-catch异常相关(part1)
1.异常概述
异常就是程序在运行时出现的不正常情况。
异常的由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象。其实就是java对不正常的情况进行描述之后的对象的体现。
对于问题的划分:
1-严重的问题, java用Error来进行描述。
就比如你的文件名是A.java,你却javac B.java,编译器都找不到public class B当然就Error了。
对于Error,一般不去编写针对性的代码对其进行处理。
2-非严重的问题,java用Exception来进行描述。
这类问题不是致命的,还能抢救下。
对于Exception可以使用针对性的处理方式进行处理。
举个栗子就是,一个人肝癌晚期和普通感冒的区别。
无论Error还是Exception都具有一些共性内容,比如不正常的信息,引发原因等。所以说向上抽取:
Throwable
|--Error
|--Exception
2.try-catch
Java提供了特有的语句进行处理。
1 try 2 { 3 //需要被检测的代码 4 } 5 catch(异常类 变量) 6 { 7 //处理异常的代码(处理方式) 8 } 9 finally 10 { 11 //一定会执行的语句 12 }
在try里面进行检测的代码如果出现异常,会将此异常包装成一个类然后传递到catch里面,然后catch里面对其进行处理。
一个栗子:
1 class Demo { 2 int div(int a, int b) { 3 return a / b; 4 } 5 } 6 7 class ExceptionDemo { 8 public static void main(String args[]) { 9 Demo d =new Demo(); 10 try 11 { 12 int x=d.div(4,0); 13 System.out.print("x="+x); 14 }catch (Exception e) 15 { 16 System.out.println("除数是零!"); 17 System.out.println(" 信息1:"+e.getMessage()); 18 //输出异常信息 19 System.out.println("信息2:"+e.toString()); 20 //输出 异常名称:异常信息 21 e.printStackTrace(); 22 //异常名称、异常信息、异常出现的位置, 23 //其实Jvm默认的异常处理机制就是在调用printStackTrace方法, 24 //打印异常的堆栈的跟踪信息 25 } 26 System.out.println("over"); 27 } 28 }
但是这么写是不Ok的,因为你把功能写出来,你并不知道别人往里面传的是什么参数,你也不知道这个功能会不会发生问题。
所以我们在写功能的时候,就需要考虑下这个玩意可能出现什么问题并表示出来,在功能上通过throws关键字声明该功能有可能会出现问题。
3.throws关键字
1 int div(int a, int b) throws Exception{ 2 return a / b; 3 }
在函数上声明异常,便于提高安全性,让调用者进行处理,不处理编译失败。
对多异常处理:
1.声明异常时,建议声明更为明确的具体的异常,这样处理的可以更具体。
1 class Demo 2 { 3 int div(int a, int b) throws ArrayIndexOutOfBoundsException, ArithmeticException 4 { 5 int[] arr=new int[a]; 6 System.out.println(arr[4]); 7 return a / b; 8 } 9 10 } 11 12 class ExceptionDemo 13 { 14 public static void main(String args[]) 15 { 16 Demo d = new Demo(); 17 try 18 { 19 int x = d.div(5, 0); 20 System.out.println("x=" + x); 21 } catch (ArithmeticException e) 22 { 23 System.out.println(e.toString()); 24 System.out.println("除数为零!"); 25 } catch (ArrayIndexOutOfBoundsException e) 26 { 27 System.out.println(e.toString()); 28 System.out.println("角标越界!!"); 29 } 30 System.out.println("over!!"); 31 } 32 }
功能抛了几个异常就应该有几个对应的相应的catch。如果出现了其他问题,我们不应该再去处理这个问题,而是应该停掉程序,以便定位问题。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
4.自定义异常与throw关键字
因为项目会出现特有的问题,而这些问题并未被Java所描述并封装对象。
所以对于这些特有的问题可以按照Java的对问题封装的思想将特有的问题进行自定义的异常封装,
也就是自定义异常。
1 //新要求:程序传入0和负数均抛出异常。 2 class FuShuExcption extends Exception 3 { 4 FuShuExcption(String msg) 5 { 6 super(msg);//因为父类中已经把异常信息的操作都完成了, 7 //所以子类只要在构造时,将异常信息通过super()传递给父类, 8 //那么就可以直接通过getMessage方法获取自定义的异常信息。 9 } 10 } 11 12 class Demo 13 { 14 int div(int a, int b) throws ArithmeticException, FuShuExcption 15 { 16 if (b < 0) 17 { 18 throw new FuShuExcption(); 19 20 } 21 return a / b; 22 } 23 24 } 25 26 class ExceptionDemo 27 { 28 public static void main(String args[]) 29 { 30 Demo d = new Demo(); 31 try 32 { 33 int x = d.div(5, 0); 34 System.out.println("x=" + x); 35 } catch (ArithmeticException e) 36 { 37 System.out.println(e.toString()); 38 System.out.println("除数为零!"); 39 } catch (ArrayIndexOutOfBoundsException e) 40 { 41 System.out.println(e.toString()); 42 System.out.println("角标越界!!"); 43 } 44 System.out.println("over!!"); 45 } 46 }
自定义异常就是让你的异常去继承Exception。那为啥要继承Exception呢?
异常体系有一个特点:因为异常类和异常对象都要被抛出,都具有可抛性,这个是Throwable这个体系中的独有特点。只有这个体系中的类和对象才可以被throw和throws操作。
当在函数内部出现了throw抛出异常对象,那么必须要给对应的处理动作,要么在内部try-catch处理,要不就在函数上让声明让调用者处理。
一般情况下,函数内出现异常,函数上需要声明。
5.throw和throws的区别
①throws使用在函数上,throw使用在函数内。
②throw后面跟的是异常类,可以跟多个,用逗号隔开。throws后面跟的是异常对象。
6.RunTimeException
Exception中有一个特殊的子类异常RunTimeException运行时异常。
对于异常分两种:
编译时被检测的异常和编译时不被检测的异常(运行时异常,RunTimeException及其子类)。
如果在函数内抛出了该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常,调用者可以不用进行处理,编译一样能过.
之所以不用在函数声明,是因为不需要让调用者处理。当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后对代码进行修正。
自定义异常:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RunTimeException。