7/31异常处理

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之间的数字:3
SQL基础
欢迎使用!

第二种情况运行结果:
找到匹配的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的课程数目:
40
S1的平均学时为: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之间的数字:3
SQL基础
欢迎使用!

输入正常,没有捕获到异常,程序正常结束。若抛出异常,可见上述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语句中,方可得到结果。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值