《Java异常》
开发工具与关键技术:MyEclipse 10、Java
作者:潘玉莹
撰写时间:2019-06-14
(一) 异常
Java的异常分为两大类:Checked异常和Runtime异常(即运行时异常)
- Runtime异常:所有的RuntimeException类及其子类的实例;
- Checked异常:不是RuntimeException类及其子类的异常实例。
只有Java语言提供了checked异常,其他语言都没有提供Checked异常。Java认为Checked异常可以被处理(修复)的异常,所以Java程序必须显式处理Checked 异常。如果程序没有处理Checked异常,该程序在编译时就会发生错误,无法通过编译。
异常:就是不正常,是指程序在运行出现的不正确的情况。其实就是程序中出现问题。这个问题按照面向对象进行描述,并封装成了对象。因为问题的产生有产生的原因、、有 问题的名称、有问题的描述等多个属性信息存在。当出现多属性信息最方便的方式就是将这 些信息进行封装。异常就是 java 按照面向对象的思想将问题进行对象封装。这样就方便于 操作问题以及处理问题。
出现的问题有很多种,比如角标越界,空指针等都是。就对这些问题进行分类。而且这 些问题都有共性内容比如:每一个问题都有名称,同时还有问题描述的信息,问题出现的位 置,所以可以不断的向上抽取。形成了异常体系。
异常的体系 Throwable
Error
通常指 JVM 出现重大问题如:运行的类不存在或者内存溢出等。 不需要编写针对代码对其处理,程序无法处理。
Exception
在运行时运行出现的一些情况,可以通过 try,catch,finally 处理
(二) 异常处理的两种方式
1、捕获异常:trycatch 直接处理可能出现的异常!
2、声明异常:throws 声明告诉调用者可能的异常,暴露问题,调用者自己处理
总结:
Exception 和 Error的子类名大都是以父类名作为后缀。
Java 异常其实是对不正常情况的一种描述,并将其封装成对象;
Java 在 设计异常体系时,将容易出现的异常情况都封装成了对象。
异常处理格式
try{
//可能出异常的代码
}catch(异常类 对象){
//处理该异常类型的语句
} [finally] {
//一定会执行的代码
//catch 块使用 System.exit(1);除外
}
备注:当 try 语句块出现异常,程序会自动跳到 catch 语句块去找匹配的异常类型,并执行 异常处理语句,finally 语句块是异常的统一出口。
(三) 多异常处理
声明异常时尽可能声明具体异常类型,方便更好的处理; 方法声明几个异常就对应有几个 catch 块; 若多个 catch 块中的异常出现继承关系,父类异常 catch 块放在最后; 在catch 语句块使用 Exception 类作为异常类型时: 所有子类实例都可以使用父类接收(向上转型),即所有的异常对象都可以使用 Exception 接 收;
注:在Java处理异常时捕获小范围的异常必须放在大范围异常之前
示例:java7- 同时捕获多个异常类型 Java7之前
try{
int a=Integer.parseInt(“1”);
intb=Integer.parseInt(“0”);
intc=a/b;
System.out.println©;
}catch(NumberFormatException
e) {
e.printStackTrace();
}catch(ArithmeticException e) {
e.printStackTrace(); }
Java7:将多个异常写到了同一个 catch 代码块
try{
Integera=Integer.parseInt(“1”);
Integerb=Integer.parseInt(“0”);
Integerc=a/b;
System.out.println©;
}catch(NumberFormatException
|ArithmeticException e){
e.printStackTrace();
}
Checked异常体现了Java的设计哲学:没有完善错误处理的代码根本就不会被执行!
(四) 、异常的分类
Runtime异常则更加灵活, Runtime异常无须显式声明抛出,如果程序需要捕获
Runtime异常,也可以使用try…catch块来实现。
异常分类:
编译时被检查异常; —>Checked 异常 在程序中必须使用 try…catch 处理;
编译时不被检测的异常; —>Runtime 异常
可以不使用 try…catch 处理,但一旦出现异常就将由 JVM 处理。
异常的分类之Runtime 异常
RuntimeException(运行时异常)是指因设计或实现方式不当而导致的问题. 说白了,就是程序员造成的,程序员小心谨慎是完全可以避免的异常.比如,事先判断对象是否 为 null 就 可 以 避 免 NullPointerException 异 常 , 事 先 检 查 除 数 不 为 0 就 可 以 避 免 ArithmeticException 异常;
特点: 这种异常Java编译器不会检查它,也就说程序中出现这类异常的时候,即使不处理也没有 问题,但是一旦出现异常,程序将异常终止,若采用异常处理,则会被相应的程序执行处理.
异常的分类之Checked 异常
除了 RuntimeException 以及子类,其他的 Exception 及其子类都是受检查异常,我们也可 以称为非 RuntimeException 异常. 特点: Java 编译器会检查它,也就说程序中一旦出现这类异常,要么是没有 try-catch 语句捕获, 或throws 语句没有声明抛出它,编译就不会通过,也就说这种异常,程序要求必须处理.
(五) 、声明异常(throws)
在可能出现异常的方法上声明抛出可能出现异常的类型: 声明的时候尽可能声明具体的异常,方便更好的处理. 当前方法不知道如何处理这种异常,可将该异常交给上一级调用者来处理(非 RuntimeException 类型的异常)。
方法一旦使用 throws 声明抛出方法内可能出现的异常类型, 该方法就可以不再过问该 异常了;
一个方法调用另一个使用 throws 声明抛出的方法,自己要么 try…catch , 要么也 throws;
格式:
public 返回值类型 方法名(参数列表…)
throws 异常类 A,异常类 B…{
}
(六) 异常
自行抛出一个异常对象,抛出异常类的对象;
若throw 抛出的是 Runtime 异常:
程序可以显示使用 try…catch 来捕获并处理,也可以不管,直接交给方法调用者处理; 若throw 抛出 Checked 异常:
要么放在 try里自己处理,要么放在一个 throws 声明的方法里面,交给调用者处理。
public static void main(String[] args){
try{
fn1(1);
}catch(Exception e){e.printStackTrace(); }
fn2(2); }
public static void fn1(int a)throws Exception{
if(a>0){thrownewException(“fn1 --a 值不合法”);} }
public static void fn2(int a){
if(a>0){thrownewRuntimeException(“a 值不合法”);}
}
throws &throw
throws 用于在方法上声明该方法不需要处理的异常类型。 throw 用于抛出具体异常类的对象
throws 与 throw的区别
thorws 用在方法上,后面跟异常类名,可以是多个异常类。
throw 用在方法内,后面跟异常对象,只能是一个。
(七) 、finally
异常的统一出口:
不管 try块程序是否异常,也不管哪个 catch 执行,finally 块总会执行。
try语句块或会执行的 catch 语句块使用了 JVM 系统退出语句例外;//System.exit(1);
try 块必须和 catch 块或和 finally 同在,不能单独存在,二者必须出现一个。
不要在finally 中使用return 或 throw 语句,否则将会导致 try、catch 中的 return 或 throw 失 效。
我的总结:finally 代码块只在一种情况下不执行:System.exit(0);
public class Demo19 {
public static void main(String[] args) {
try{
System.out.println(17/0);
}catch(Exception e){ //e.printStackTrace();
System.out.println("程序错误,请修正!
}finally{
System.out.println(“这是finally代码块!”);
} } }
输出:
程序错误,请修正!
这是finally代码块!
(八) throw 和 catch 同时使用
当异常出现在当前方法中,程序只对异常进行部分处理,还有一些处理需要在方法的调用 者中才能处理完成,此时还应该再次抛出异常,这样就可以让方法的调用者也能捕获到异常;
示例
public staticvoid buy(String price)throws Exception {
try{
if(price!= null)
Double.parseDouble(price);
}catch(Exception e){
e.printStackTrace();
thrownewException(“价格不能只能是数字组成”);
} }
public staticvoid main(String[] args) {
try{
buy(null);
}catch(Exception e){
System.out.println(e.getMessage());
}
}