Java学习day26-捕获异常和抛出异常

一、异常处理机制

1.在编写程序时,经常要在可能出现错误的地方加上检测的代码,如进行x/y的计算时,要检测分母为0、数据为空、输入的不是数据而是字符等问题。过多的分支会导致程序的代码加长,可读性差。因此采用异常处理机制。

2.Java异常处理:Java采用异常处理机制,将异常处理的程序代码集中到一起,与正常的程序代码分开,使得程序简洁,并易于维护。

3.Java提供的是异常处理的抓抛模型。

4.Java程序执行过程中如出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统,这个过程称为抛出(throw)异常

5.如果一个方法内抛出异常,该异常会被抛到调用方法中。如果异常没有在调用方法中处理,它将继续被抛给这个调用方法的调用者,这个过程将一直持续下去,直到异常被处理。这一过程称为捕获(catch)异常

6.如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。

7.程序员通常只能处理Exception,而对Error无能为力。

二、实例1.使用try-catch语句处理异常

package day16;

public class Test {
    public static void main(String[] args){
        int i = 0;
        try{//用try{}来扩住一段有可能出现异常的代码段
        System.out.println(3/i);//被除数不能为0,由于异常,使中断,可以通过异常处理机制防止程序的中断
        }catch(Exception e){//当你不知道捕获的是什么类型异常时,可以直接使用所有异常的父类Exception
            e.printStackTrace();//提示什么类型的异常
            System.out.println(e.getMessage());//或者输出getMessage的异常类型
        }
        
        System.out.println("ok");
    }
}

打印结果为:

实例2,异常处理是通过try-catch-finally语句实现的。

try{
    ......    //可能产生异常的代码
}catch(ExceptionName1 e)
{
    ......    //当产生ExceptionName1型异常时的处置措施
}catch(ExceptionName2 e)
{
    ......    //当产生ExceptionName2型异常时的处置措施
}finally{
    ......    //无条件执行的语句
}
package day16;

public class Test {
    public static void main(String[] args){

        String[] strs = new String[]{"a","b"};
        A a = null;
        
        //try-catch是为了防止程序可能出现的异常
        //在捕获异常的代码块中(指try()里面的代码),如果前面的代码块有异常了,就不会执行后面的代码块了
        try{
        System.out.println(strs[2]);//数组越界
        System.out.println(a.i);//空指针
        }catch(ArrayIndexOutOfBoundsException e1){
            System.out.println(e1.getMessage());
            e1.printStackTrace();
        }catch(NullPointerException e2){
            System.out.println(e2.getMessage());
            e2.printStackTrace();
        }finally{//finally可写可不写,finally是捕获异常体系中最终一段会执行的部分,在IO操作和JDBC中广泛应用
            System.out.println("最终输出不受影响");
        }
        
    }
}

打印结果为:

三、捕获异常总结

(1)try

捕获异常的第一步是用try{...}语句块选定捕获异常的范围,将可能出现异常的代码放在try语句块中。

(2)catch(Exceptiontype e)

在catch语句块中是对异常对象进行处理的代码。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。

(3)如果明确知道产生的是何种异常,可以用该异常作为catch的参数,也可以用其父类作为catch的参数。

  可以用ArithmeticException类作为参数,也可以用RuntimeException类作为参数,或者用所有异常的父类Exception作为参数。

(4)捕获异常的有关信息:

  与其他方法一样,可以访问一个异常对象的成员变量或调用它的方法。

  ①getMessage()方法,用来得到有关异常事件的信息。

  ②printStackTrace()用来跟踪异常事件发生时执行堆栈的内容。

(5)finally

  捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其他部分以前,能够对程序的状态作统一的管理。不论在try-catch代码块中是否发生了异常事件,finally块中的语句都会被执行。(finally语句是可选的)

三、声明抛出异常

1.声明抛出异常时Java中处理异常的第二种方式

  ①如果一个方法中的语句执行时可能造成某种异常,但是并不能确定如何处理这种异常,则此方法应显式的声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。

  ②在方法声明中用 throws 子句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

2.声明抛出异常举例:

public void readFile(String file) throws FileFoundException{
    ... ...
    //读文件操作可能产生FileFoundException类型的异常
    FileInputStream fis = new  FileInputStream(file);
    ... ...
}
package day16;

public class Test1 {
    public static void main(String[] args){//可以在main方法中继续抛出异常
        //main方法抛出的异常直接抛到虚拟机去了,在程序中就无法处理了
        B b = new B();
        try {//throws在代码中抛出的异常,在调用方法中捕获处理
            b.test();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class B{
    int i;
    public void test() throws Exception{//可以使用throws在代码这抛出异常,在调用方法中去捕获处理
        B b = null;
        System.out.println(b.i);
    }
}

打印结果为:

3.重写方法声明抛出异常的原则

重写方法不能抛出比被重写方法范围更大的异常类型
//重写方法不能抛出比被重写方法范围更大的异常类型
public class A{
        public void methodA() throws OException{
           ... ...
        }
}
public class B1 extends A{
        public void methodA() throws FileNotFoundException{
           ... ...
        }
}
public class B2 extends A{
        public void methodA() throws Exception{//error 子类重写父类的方法时,子类不能抛出比父类方法更大的异常
           ... ...
        }
}
package day16;

public class Test1 {
    public static void main(String[] args){//可以在main方法中继续抛出异常
        //main方法抛出的异常直接抛到虚拟机去了,在程序中就无法处理了
        B b = new B();
        try {//throws在代码中抛出的异常,在调用方法中捕获处理
            b.test();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class B{
    int i;
    //NullPointerException的父类是Exception
    public void test() throws NullPointerException{//可以使用throws在代码这抛出异常,在调用方法中去捕获处理
        B b = null;
        System.out.println(b.i);
    }
}

class C extends B{
//    public void test() throws Exception{//重写方法不能抛出比被重写方法范围更大的异常类型,系统会报错
    public void test() throws NullPointerException {

        // TODO Auto-generated method stub
        super.test();
    }
}

4.人工抛出异常

(1)Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可以根据需要人工创建并抛出

  ①首先要生成异常类对象,然后通过throws语句实现抛出操作(提交给Java运行环境)。

IOException e = new IOException();
throw e;

  ②可以抛出的异常必须是Throwable或者其子类的实例。

package day16;

public class Test1 {
    public static void main(String[] args){
        
        B b = new B();
        try {
            b.test1(200);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class B{
    
    int age;
    
    public void test1(int age) throws Exception{
        if(age >= 0 && age <= 150){
            this.age = age;
            System.out.println("年龄是:" + this.age);
        }else{
            throw new Exception("年龄在0到150之间");
        }
    }
}

打印结果为:

5.创建用户自定义异常类

(1)用户自定义异常类MyException, 用于描述数据取值范围错误信息。用户自己的异常类必须继承现有的异常类。

(2)创建完成后可以使用用户自定义异常类

package day16;

public class Test1 {
    public static void main(String[] args){
        
        B b = new B();
        try {
            b.test2(-100);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class B{
    
    int age;
    
    public void test2(int age) throws MyException{
        if(age >= 0 && age <= 150){
            this.age = age;
            System.out.println("年龄是:" + this.age);
        }else{
            throw new MyException("年龄在0到150之间");
        }
    }
}

class MyException extends Exception{
    public MyException(String msg){
        super(msg);
    }
}

Java提供的异常的类一般是够用的,只有特殊的情况才可能需要自己编写异常类,这种情况很少见。

猜你喜欢

转载自www.cnblogs.com/su-peng/p/12545490.html