java异常分为两种,Checked异常和Runtime异常,Checked异常可以在编译阶段被处理的异常,强制处理所有
Checked异常,Runtime异常则无需处理
java的异常机制主要依赖try,catch,finally,throw,throws五个关键字
throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常
throw用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象
throw与throws的比较
1、throws跟在方法签名后,可以声明抛出多个异常类(逗号间隔),调用带throws声明的方法,要么将该方法放在try catch中显示捕获该异常,要么放在另一个带throws声明抛出的方法中;而throw出现在函数体。
2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常实例,而且每次只能抛出一种异常实例。
3、throws声明抛出异常时有一个限制,就是方法重写时“两小”中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出异常类型的子类或相同类,子类声明抛出的异常不允许比父类方法声明抛出的异常多。(子类不能比父类犯更多的错误)
4、两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
java的异常处理机制:当程序出现异常,系统生成一个Exception对象通知程序,从而将实现业务功能实现和错误处理分离
10.2.2 异常类的继承体系
java运行时环境接收到异常对象后,会依次判断该异常对象是否是catch块后异常类或其子类的异常实例,如果是,java运行时环境将调用该catch块来处理该异常,否则将拿该异常对象和下一个catch块的异常类进行比较。
当程序进入负责处理异常的catch块时,系统生成的异常对象ex将会传给异常块后的异常形参,从而允许catch块通过该对象来获取异常的详细信息。
try块后的多个catch块只有一个被执行。
java异常类之间的继承关系:java将所有非正常的情况分为两类,异常(Exception)和错误(Error),他们都继承Throwable父类
Error错误一般指与虚拟机相关的问题,如系统崩溃,虚拟机错误,动态链接失败等,这些错误无法恢复或不可捕获,将导致应用程序中断。
Exception是可以被抛出的异常类。RuntimeException继承自Exception(如NullPointerException),表示运行时异常,JVM会自动抛出。
进行异常捕获时,先处理小异常,再处理大异常。
10.2.4 访问异常信息
java运行时决定调用某个catch块处理该异常时,会将异常对象赋给catch块后的异常参数,异常对象包含以下几个方法
getMessage(),printStackTrace(),printStackTrace(PrintStream s),getStackTrace()
10.2.5 finally
异常处理语法结构中只有try块时必须的,catch和finally都是可选的,但catch和finally至少出现其中之一,也可以同时出现,finally一定会被执行。
通常情况下,一旦方法里执行到return语句的地方,程序将立即结束该方法,虽然return语句也强制方法结束,但一定会先执行finally块里的代码。
如果在try,catch中调用退出虚拟机的方法,则finally块将失去执行的机会。
当java程序执行try块、catch块时遇到return或throw语句,这两个语句会导致该方法立即结束,但系统执行这两个语句并不会立即结束该方法,而是去寻找该异常处理流程中是否包含finally块,如果没有,程序执行return或throw语句,方法终止。如果有finally块,系统立即执行finally块,只有当finally块执行完成,系统会再次跳回来执行try,catch块里的return或throw语句,如果finally块也使用了return或throw等导致方法终止的语句,finally块已经终止了方法,系统将不会跳回去执行try,catch中的任何代码。
10.4 使用throw抛出异常
当程序出现错误时,系统会自动抛出异常,除此之外,java也允许程序自行抛出异常,自行抛出异常使用throw语句完成。
throw 语句抛出的不是异常类而是一个异常实例,而且每次只能抛出一个异常实例。eg:throw ExceptionInstance
如果throw语句抛出的异常是Checked异常,则该throw语句要么处于try块里,显式捕获该异常;要么放在带throws声明
抛出的方法中,即把该异常交给该方法的调用者处理。如果throw语句抛出的异常是Runtime异常,则该语句无须放在try块
里,也无须放在带throws生命抛出的方法中,程序既可以显式使用try...catch来捕获该异常,也可以完全不理会该异常
,把该异常交给方法调用者处理。
10.4.2 自定义异常类
自定义异常类通常继承Exception基类,如果希望自定义Runtime异常,则应继承RuntimeException基类。定义异常类通常
要提供两个构造器:一个是无参数的构造器,另一个是带一个字符串参数的构造器,这个字符创将作为异常对象的描述
信息(getMessage()返回值),其执行体是通过super来调用父类的构造器。
public class MyException extends Exception{
public MyException(){}
public MyException(String msg){
super(msg);
}
//10.4.4
public MyException(Throwable t){
super(t);
}
}
10.4.3 catch 中使用 throw
出现异常的方法内捕获并处理异常,该方法的调用者再次处理该异常
10.4.4 异常链
常常会再捕获一个异常后跑出另外一个异常,并且希望把异常原始信息保存下来,这被称为异常链。
现在所有Throwable的子类子构造器中都可以接受一个cause对象作为参数,这个cause就异常原由,代表着原始异常,
即使在当前位置创建并抛出行的异常,也可以通过这个cause追踪到异常最初发生的位置。
只有Error,Exception,RunimeException提供了带cause参数的构造器,其他的所以异常就只有通过initCause()来设置cause了。
10.6 异常处理规则
不要过度使用异常,不要使用过于庞大try块,避免使用Catch All语句,不要忽略捕获到的异常
Checked异常,Runtime异常则无需处理
java的异常机制主要依赖try,catch,finally,throw,throws五个关键字
throws关键字主要在方法签名中使用,用于声明该方法可能抛出的异常
throw用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象
throw与throws的比较
1、throws跟在方法签名后,可以声明抛出多个异常类(逗号间隔),调用带throws声明的方法,要么将该方法放在try catch中显示捕获该异常,要么放在另一个带throws声明抛出的方法中;而throw出现在函数体。
2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常实例,而且每次只能抛出一种异常实例。
3、throws声明抛出异常时有一个限制,就是方法重写时“两小”中的一条规则:子类方法声明抛出的异常类型应该是父类方法声明抛出异常类型的子类或相同类,子类声明抛出的异常不允许比父类方法声明抛出的异常多。(子类不能比父类犯更多的错误)
4、两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
java的异常处理机制:当程序出现异常,系统生成一个Exception对象通知程序,从而将实现业务功能实现和错误处理分离
10.2.1 try catch 捕获异常
如果try块里的业务逻辑代码出现异常,系统自动生成一个异常对象,该异常对象提交给Java运行时环境,这个过程称为抛出异常当java运行环境收到异常对象时,会寻找处理该异常对象的catch块,如果找到合适的catch块,则把该异常对象交给catch块处理,这个过程叫捕获异常,如果java运行时环境找不到捕获异常的catch块,则java运行时环境终止,java程序将退出。10.2.2 异常类的继承体系
java运行时环境接收到异常对象后,会依次判断该异常对象是否是catch块后异常类或其子类的异常实例,如果是,java运行时环境将调用该catch块来处理该异常,否则将拿该异常对象和下一个catch块的异常类进行比较。
当程序进入负责处理异常的catch块时,系统生成的异常对象ex将会传给异常块后的异常形参,从而允许catch块通过该对象来获取异常的详细信息。
try块后的多个catch块只有一个被执行。
java异常类之间的继承关系:java将所有非正常的情况分为两类,异常(Exception)和错误(Error),他们都继承Throwable父类
Error错误一般指与虚拟机相关的问题,如系统崩溃,虚拟机错误,动态链接失败等,这些错误无法恢复或不可捕获,将导致应用程序中断。
Exception是可以被抛出的异常类。RuntimeException继承自Exception(如NullPointerException),表示运行时异常,JVM会自动抛出。
进行异常捕获时,先处理小异常,再处理大异常。
10.2.4 访问异常信息
java运行时决定调用某个catch块处理该异常时,会将异常对象赋给catch块后的异常参数,异常对象包含以下几个方法
getMessage(),printStackTrace(),printStackTrace(PrintStream s),getStackTrace()
10.2.5 finally
异常处理语法结构中只有try块时必须的,catch和finally都是可选的,但catch和finally至少出现其中之一,也可以同时出现,finally一定会被执行。
通常情况下,一旦方法里执行到return语句的地方,程序将立即结束该方法,虽然return语句也强制方法结束,但一定会先执行finally块里的代码。
如果在try,catch中调用退出虚拟机的方法,则finally块将失去执行的机会。
当java程序执行try块、catch块时遇到return或throw语句,这两个语句会导致该方法立即结束,但系统执行这两个语句并不会立即结束该方法,而是去寻找该异常处理流程中是否包含finally块,如果没有,程序执行return或throw语句,方法终止。如果有finally块,系统立即执行finally块,只有当finally块执行完成,系统会再次跳回来执行try,catch块里的return或throw语句,如果finally块也使用了return或throw等导致方法终止的语句,finally块已经终止了方法,系统将不会跳回去执行try,catch中的任何代码。
10.2.7 Java7的自动关闭资源的try语句
java7增强try语句的功能-它允许try关键字后紧跟一对圆括号,圆括号可以声明或初始化一个多个必须在程序结束时显示关闭的资源,try语句在该语句结束时自动关闭这些资源。ps:这些资源实现类必须实现AutoCloseable或Closeable接口,实现这两个接口就必须实现close()方法
10.3 Checked异常和Runtime异常体系
java的异常被分为两大类:Checked和Runtime异常。所有的RuntimeException类及其子类的实例被称为Runtime异常,不是RuntimeException类及其子类的异常实例则被称为Checked异常。10.4 使用throw抛出异常
当程序出现错误时,系统会自动抛出异常,除此之外,java也允许程序自行抛出异常,自行抛出异常使用throw语句完成。
throw 语句抛出的不是异常类而是一个异常实例,而且每次只能抛出一个异常实例。eg:throw ExceptionInstance
如果throw语句抛出的异常是Checked异常,则该throw语句要么处于try块里,显式捕获该异常;要么放在带throws声明
抛出的方法中,即把该异常交给该方法的调用者处理。如果throw语句抛出的异常是Runtime异常,则该语句无须放在try块
里,也无须放在带throws生命抛出的方法中,程序既可以显式使用try...catch来捕获该异常,也可以完全不理会该异常
,把该异常交给方法调用者处理。
10.4.2 自定义异常类
自定义异常类通常继承Exception基类,如果希望自定义Runtime异常,则应继承RuntimeException基类。定义异常类通常
要提供两个构造器:一个是无参数的构造器,另一个是带一个字符串参数的构造器,这个字符创将作为异常对象的描述
信息(getMessage()返回值),其执行体是通过super来调用父类的构造器。
public class MyException extends Exception{
public MyException(){}
public MyException(String msg){
super(msg);
}
//10.4.4
public MyException(Throwable t){
super(t);
}
}
10.4.3 catch 中使用 throw
出现异常的方法内捕获并处理异常,该方法的调用者再次处理该异常
10.4.4 异常链
常常会再捕获一个异常后跑出另外一个异常,并且希望把异常原始信息保存下来,这被称为异常链。
现在所有Throwable的子类子构造器中都可以接受一个cause对象作为参数,这个cause就异常原由,代表着原始异常,
即使在当前位置创建并抛出行的异常,也可以通过这个cause追踪到异常最初发生的位置。
只有Error,Exception,RunimeException提供了带cause参数的构造器,其他的所以异常就只有通过initCause()来设置cause了。
10.6 异常处理规则
不要过度使用异常,不要使用过于庞大try块,避免使用Catch All语句,不要忽略捕获到的异常