7/31异常处理

来源:互联网 发布:编程c语言初级教程 编辑:程序博客网 时间:2024/06/05 20:09

7/31异常处理

概述:

1、异常就是在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。

2、Java编程语言使用异常处理机制为程序提供了错误处理的能力。

3、Exception和Error都是Throwable的子类:

Error:Error 类的异常为内部错误,正常情况下不期望用户的程序捕获它们 。

Exception:异常层级结构的根类。

千万不要拿异常当错误处理!!!

4、两种类型:

CheckedException:Checked Exception是会显示提示错误的异常;
UncheckedException:而Unchecked Exception是不会提示错误信息,但运行时会打印异常信息的异常。
如下图:
这里写图片描述

异常五个关键字:

try、catch、finally、throw、throws

详解如下:

这里写图片描述

异常处理块的一般形式:

try-catch语句的三种情况

1、情况一:程序不发生异常,try语句执行完成后,跳过catch块,执行try-catch后面的语句。

2、情况二:程序发生异常,产生了异常对象,将异常对象与后面的catch块进行匹配,找到匹配的catch块,进入catch块,执行catch语句,完成后,执行try-catch块后面的语句。

3、情况三:程序发生异常,产生异常对象,没有找到匹配的catch块,程序运行中断。

三种情况对于同一个程序的不同结果:

import java.util.Scanner;public class HelloAccp {    public static void main(String[] args) {        System.out.print("请输入1至3之间的数字:");        Scanner s = new Scanner(System.in);        try{            int courseCode = s.nextInt();            switch(courseCode){                case 1:                    System.out.println("C#编程");                    break;                case 2:                    System.out.println("JAVA编程");                    break;                case 3:                    System.out.println("SQL基础");            }        }catch(Exception se){        System.out.println("请输入数字!");        se.printStackTrace();        }        System.out.println("欢迎使用!");    }}第一种情况运行结果:请输入13之间的数字:3SQL基础欢迎使用!

第二种情况运行结果:
找到匹配的catch块,异常处理后,后面的语句继续执行。
这里写图片描述

第三种情况运行结果:(运行前先将catch语句中的Exception改成NullPointerException,为了找不到匹配的catch块)
没有找到匹配的catch语句,程序中断,后面的语句不再执行。
这里写图片描述

try-catch-finally:(异常处理的一般情况)

try必须有,catch或finally至少有一个!且finally有的话,最多只能有一个;而catch块可以有多个。

无论try中的异常是否找到匹配的catch语句,finally块都会执行。

多重的catch语句:

一段代码中,一个try块可以有多个catch块;当引发异常时,会按顺序来依次查看每个 catch 语句,并执行第一个与异常类型匹配的catch语句;

执行其中的一条 catch 语句之后,其后的 catch 语句将被忽略 。

如下面代码:

public class AccpException4 {    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        try{            System.out.print(“请输入S1的总学时:");            int totalTime = in.nextInt(); //总学时            System.out.print(“请输入S1的课程数目:");            int totalCourse = in.nextInt(); //课程数目            System.out.println(“S1各课程的平均学时为:"+ totalTime / totalCourse);        } catch (InputMismatchException e1) {            System.out.println("输入不为数字!");        } catch (ArithmeticException e2) {            System.out.println("课程数目不能为零!");        } catch (Exception e) {            System.out.println("发生错误:"+e.getMessage());        }    }}

对上述代码进行三种情况的测试:

如下面测试结果:**输入正常的情况:**请输入S1的总学时:260请输入S1的课程数目:40S1的平均学时为:6**输入的学时不是数字:**请输入S1的总学时:asd输入不为数字!**输入的课程数为零的情况:**请输入S1的总学时:1200请输入S1的课程数目:0课程数目不能为0!

try-catch、try-catch-finally、throws的区别:

1、try-catch语句:如果try程序块里面捕获到的异常,在catch块中可以找到相匹配的catch语句,则处理异常后,try-catch块后面的语句还会继续执行;但如果没有找到相匹配的catch块,则程序将就此中断,后面的语句不会再执行。

如下列程序:

import java.util.Scanner;public class HelloAccp {    public static void main(String[] args) {        System.out.print("请输入1至3之间的数字:");        Scanner s = new Scanner(System.in);        try{            int courseCode = s.nextInt();            switch(courseCode){                case 1:                    System.out.println("C#编程");                    break;                case 2:                    System.out.println("JAVA编程");                    break;                case 3:                    System.out.println("SQL基础");            }        }catch(Exception se){            System.out.println("请输入数字!");            se.printStackTrace();        }        System.out.println("欢迎使用!");    }}运行结果:请输入13之间的数字:3SQL基础欢迎使用!

输入正常,没有捕获到异常,程序正常结束。若抛出异常,可见上述try-catch的第二种情况可以找到匹配的catch块的详解。

2、而在try-catch-finally语句中,无论有多少个catch语句,无论是否找到匹配的catch,finally语句都会执行。

示例代码如下:

public class HelloAccp {    public static void main(String[] args) {        System.out.print("请输入1至3之间的数字:");        Scanner s = new Scanner(System.in);        try{                    int courseCode = s.nextInt();                    switch(courseCode){                        case 1:                            System.out.println("C#编程");                            break;                        case 2:                            System.out.println("JAVA编程");                            break;                        case 3:                            System.out.println("SQL基础");                    }                }catch(NullPointerException se){//异常类型不匹配!                    System.out.println("请输入数字!");                    se.printStackTrace();                }finally{                    //无论是否匹配都会执行                    System.out.println("欢迎使用!");                }            }}运行结果:请输入13之间的数字:qwe欢迎使用!Exception in thread "main" java.util.InputMismatchException    at java.util.Scanner.throwFor(Unknown Source)    at java.util.Scanner.next(Unknown Source)    at java.util.Scanner.nextInt(Unknown Source)    at java.util.Scanner.nextInt(Unknown Source)    at 实训731.HelloAccp.main(HelloAccp.java:10)

3、如果在方法中throws声明异常,在异常发生后,处理异常,后面的语句不会再执行。

代码示例:

public class MyException extends Exception{    private int i;    MyException(int a){        i = a;    }    public String toString(){        return i+"大于10啦!";    }}public class MyExceptionTest {    static void go(int a) throws MyException{        System.out.println("a="+a);        if(a>10){            throw new MyException(a);        }        System.out.println("正常结束!");        //在throws里面,检测到异常后,后面的语句将不再被执行    }    public static void main(String[] args) {        try{            go(1);            go(15);//后面的正常结束将不再被输出        }catch(MyException e){            System.out.println("捕获异常:"+e);        }    }}运行结果:a=1正常结束!a=15捕获异常:15大于10啦!

在本例中,go(15);在执行的过程中抛出异常,后面的正常结束将不会再输出。


Java常见异常类:

这里写图片描述


用户自定义异常

在另一个方法中捕获并处理异常
在一个方法中使用throw抛出异常
为该异常类添加构造方法
创建一个类继承 Exception 或其子类


随堂练习:

1.编写如下异常类:
空异常(NullException ,年龄低异常(LowAgeException),年龄高异常(HeightAgeException),
工资低异常(LowSalaryException),工资高异常(HighSalaryException),身份证非法异常(IdCardException)
2.编写一个员工类,
(1) 有属性:
编号,姓名,年龄,工资,身份证号码,员工人数(10),员工工资总额(10000)
(2) 有构造器:
构造器1:设置编号,年龄,姓名;如果年龄小于18,抛出年龄低异常;如果年龄大于60
抛出年龄高异常,如果姓名为null或为空字符串,抛出空异常。
构造器2:设置工资,设置身份证号码;如果工资低于600,抛出工资低异常。
如果身份证不是18位,抛出身份证非法异常。
(3) 有方法
增加工资 addSalary(double addSalary),抛出工资高异常,当增加后的工资大于员工工资总额时,抛出此异常。
减少工资 minusSalary(double minusSalary), 抛出工资低异常,当减少后的工资低于政府最低工资时,抛出工资低异常。
显示员工工资总额方法:showTotalSalary(),抛出空异常,当工资总额为0时,抛出此异常。
显示员工人数:voidshowTotalEmployee(),抛出空异常。当员工人数为0时,抛出此异常
3.编写main主测试类
分别生成3个员工,测试构造方法的异常抛出。
每个员工分别增加,减少工资,测试方法的异常。
显示员工的人数和工资总额。

public class Employee {    private int id;    private String name;    private int age;    private double salary;    private String id_card;    private int totalEmployee = 10;    private double totalSalary = 1000;    public Employee(int id1,String name1,int age1) throws Exception{        if(age1<18){            throw new LowAgeException("年龄太小!");        }else if(age1>60){            throw new HighAgeException("年龄太大!");        }        if(name1==null||name1==""){            throw new NullException("姓名为空!");        }    }    public double getSalary() {        return salary;    }    public Employee(double salary1,String id_card1) throws Exception{        this.salary = salary1;        if(salary<600){            throw new LowSalaryException("工资太低!");        }        if(id_card1.length()!=18){            throw new IdCardException("身份证号不是18为!");        }    }    public void addSalary(double addsalary) throws Exception{        double salary_add = salary + addsalary;        System.out.println("增加后的工资为:"+salary_add);        if(salary_add>totalSalary){            throw new HighSalaryException("增加后的工资太高!");        }    }    public void minusSalary(double minusSalary) throws Exception{        salary = salary - minusSalary;        if(salary<600){            throw new LowSalaryException("减少后的工资低于政府工资!");        }    }    public void showTotalSalary(double sum) throws NullException{        //double totalSalary = 0;        System.out.println("工资总额为:"+sum);        if(sum == 0){            throw new NullException("工资总额为零!");        }    }    public void showTotalEmployee(int num) throws NullException{        System.out.println("员工人数为:"+num);        if(num == 0){            throw new NullException("员工人数为零!");        }    }}

Test测试类:

public class Test {    public static void main(String[] args){        double sum = 0;        int num=0;        try {            //测试年龄低异常            Employee employee = new Employee(12,"tom",15);            sum = sum + employee.getSalary();            num = num + 1;            //测试低工资异常            employee = new Employee(200,"123456789012345678");            sum = sum + employee.getSalary();            num = num + 1;            //测试年龄高异常            employee = new Employee(12,"tom",65);            sum = sum + employee.getSalary();            num = num + 1;            //测试名字为空异常            employee = new Employee(12,"",24);            sum = sum + employee.getSalary();            num = num + 1;            //测试身份证不够18位异常            Employee employee1 = new Employee(700,"1234567890");            sum = sum + employee1.getSalary();            num = num + 1;            //增加工资后大于1000的异常            employee = new Employee(700,"123456789012345678");            sum = sum + employee.getSalary();            num = num + 1;            employee.addSalary(500);            //减少工资后小于600            employee = new Employee(1000,"123456789012345678");            sum = sum + employee.getSalary();            num = num + 1;            employee.minusSalary(500);            //正常            employee = new Employee(1200,"123456789012345678");            sum = sum + employee.getSalary();            num = num + 1;            //正常            employee = new Employee(1500,"123456789012345678");            sum = sum + employee.getSalary();                       num = num + 1;            employee.showTotalSalary(sum);            employee.showTotalEmployee(num);        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }     }}

六个异常类:

//年龄高异常public class HighAgeException extends Exception{    public HighAgeException(String message){        super(message);    }}//工资高异常public class HighSalaryException extends Exception{    public HighSalaryException(String message){        super(message);    }}//身份证异常public class IdCardException extends Exception{    public IdCardException(String message){        super(message);    }}//年龄低异常public class LowAgeException extends Exception{    public LowAgeException(String message){        super(message);    }}//工资低异常public class LowSalaryException extends Exception{    public LowSalaryException(String message){        super(message);    }}//空异常public class NullException extends Exception{    public NullException(String message){        super(message);    }}

运行结果:
这里写图片描述
对上述Test测试类,将每个测试内容放到一个try-catch语句中,方可得到结果。