java的异常分类?
Exception(异常)
是程序本身可以处理的异常。主要包含RuntimeException等运行时异常和IOException,SQLException等非运行时异常。
运行时异常 包括:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常(编译异常) 包括:RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常
checked异常和runtime异常/编译时异常和运行时异常
java认为checked异常都是在编译阶段被处理的异常,所以他强制程序处理所有的checked异常
java认为runtime异常由于在运行期间才能检查出来,因此不对runtime异常做处理
因此我们作为开发者,日常处理的就是Checked异常,java要求程序员在编译时解决checked异常
解决checked异常的异常机制主要依赖于try/catch/finally/throw/throws五个关键字?
java的异常机制可以让程序具有极好的容错性,程序更健壮
(false/true/null不是关键字,是常量值)
try{
//放置可能引发异常的代码,系统自动的生成一个异常对象(抛出异常:jvm将系统自动生成的异常对象抛给jvm的运行环境,jvm运行环境再将异常对象抛给合适的catch块去解决该异常对象,如果没有合适的,java就会认为没有处理编译时异常,从而编译时报错)
}
catch(对应异常){//由java运行环境进行赋值,允许catch块通过该对象获得异常的详细信息,传地址值,操纵同一个异常对象
//catch处理系统抛出的异常对象
//中存放处理某种异常类型对象的代码,增加程序的健壮性和容错性
//每个catch块都是专门用于处理该异常类及其子类的异常实例
//调用异常对象的方法,访问异常对象的信息
}
【总结:如果try中引发了异常,jvm会在内存中创建一个异常对象,会依次判断该异常对象是否是catch块的异常类或其子类的实例,该异常对象必须被catch处理,不然会引起编译时错误】
finally{
//用来回收在tyr块中打开的物理资源,异常机制保证finally块总被执行,即使try/catch块中有return语句,也还是会先执行finally块
//但是如果有System.exit(1);/退出虚拟机,则finally块不会执行
//java的垃圾回收机制不会回收任何物理资源,因此只能显示的回收物理资源
}
throws关键字主要在方法签名时使用,用于声明该方法可能抛出的异常
throw关键字用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象
java常见非正常情况的继承体系?
父类:非正常父类Throwable
public class Throwable implements Serializable {
}
两大子类:
异常子类Exception
public class Exception extends Throwable {
}
异常子类下的子类:RuntimeException/IOException/SQLException(checked异常和runtime异常)
程序必须处理checked异常,如果不处理,那么会出现编译错误,
处理checked异常的两种方式:(1)try/catch/finally显示捕获并处理他
(2)throws显示声明抛出(throws是在不知道如何处理这种类型的异常时调用的,抛出的异 常由上一级调用者处理,main()方法的调用者jvm
【重写时,要求子类方法不许比父类方法声明抛出的异常多,也不允许比父类抛出的异常类型大】
程序可以捕获runtime异常
谁会抛出异常对象?
1虚拟机:虚拟机自动抛出异常对象,抛出的异常对象要么被catch捕获处理,要么就交还给其上一级调用者处理
2自定义抛出:throw new Exception();抛出的异常对象(checked/runtime异常)要么被catch捕获处理,要么就交还给其上一级调用者处理
Runtime子类下的子类:IndexOutOfBoundsException/NullPointerException/ClassCastException
错误子类Error
public class Error extends Throwable {
}
错误子类Error下的子类:AWTError /IOError/LinkageError/ThreadDeath
Error:一般☞的是与虚拟机相关的问题,系统崩溃,虚拟机错误,动态链接失败,这种错误无法恢复/不可能捕获,将导致应用程序中断,应用程序无法处理这些错误,因此catch块不能用来捕捉Error及其子类的实例
java7提供了多异常捕获
即每个catch块可以捕获多种类型的异常
try{
}
catch(IndexOutOfException | NumberFormatException | ArithmeticException e){
e=new IndexOutOfException();(捕获多种类型的异常时,异常变量有隐式的final修饰
有异常类型的变量前有隐式的final修饰,因此不可再赋值) 错
}
catch(IndexOutOfException e){
e=new IndexOutOfException() //异常变量没有final修饰 对
}
}
java7提供的自动关闭资源的try语句
在try后进更一堆圆括号,圆括号可以声明,初始化一个或多个资源,try语句在该语句结束时自动关闭这些资源
(这些资源实现类必须实现AutoCloseable接口 | Closeable接口,实现他们的close方法)
java7try的新特性相当于包含了隐式的finally块,因此这个try语句可以不包含catch块,也不包含finally块
嗯~ o(* ̄▽ ̄*)o,java7几乎把所有的资源类进行了改写,改写后的资源类都实现了AutoCloseable接口 | Closeable接口,
自定义异常类?
自定义异常类需要继承对相应的异常类,
public class MyException extends Exception{
public MyException(){}
public MyException(String msg){
super(msg);
}
打印java的异常跟踪栈信息?
e.printStackTrace(),这个方法可以帮助我们追踪异常的发生情况,可以在程序调试的时候使用,但是对异常对象的正确处理是处理他,
异常处理的规则?
(1)不要用过于庞大的try块
(2)避免使用catch all语句 catch(Throwable t){}
(3)适当的处理捕获到的异常,不要只是打印异常信息
(4)对于不清楚如何处理的异常,让上层调用者去处理该异常throws