3.6异常处理

    科技2024-10-01  23

    异常处理

    目标

    处理异常

    明确什么是异常 (重点)能辨识出常见的异常及其含义。 (熟悉+)理解异常产生的原理 (了解)能处理异常 (重点)能够自定义异常类型 (熟悉)

    什么是异常?

    异常是在程序中导致程序中断运行的一种指令流。 例如,现在有如下的操作代码:

    public class ExceptionDemo01{ public static void main(String argsp[]){ int i = 10 ; int j = 0 ; System.out.println("============= 计算开始 =============") ; int temp = i / j ; // 进行除法运算 System.out.println("temp = " + temp) ; System.out.println("============= 计算结束 =============") ; } };

    运行结果: ============= 计算开始 ============= Exception in thread “main” java.lang.ArithmeticException: / by zero at ExceptionDemo01.main(ExceptionDemo01.java:6) 以上的代码在“int temp = i / j ;”位置处产生了异常,一旦产生异常之后,异常之后的语句将不再执行了,所以现 在的程序并没有正确的执行完毕之后就退出了。 那么,为了保证程序出现异常之后仍然可以正确的执行完毕,所以要采用异常的处理机制。

    处理异常

    如果要想对异常进行处理,则必须采用标准的处理格式,处理格式语法如下: try{ // 有可能发生异常的代码段 }catch(异常类型1 对象名1){ // 异常的处理操作 }catch(异常类型2 对象名2){ try+catch的处理流程 finally 异常体系结构 // 异常的处理操作 } … finally{ // 异常的统一出口 }

    try+catch的处理流程 1、 一旦产生异常,则系统会自动产生一个异常类的实例化对象。 2、 那么,此时如果异常发生在try语句,则会自动找到匹配的catch语句执行,如果没有在try语句中,则会将异常抛出. 3、 所有的catch根据方法的参数匹配异常类的实例化对象,如果匹配成功,则表示由此catch进行处理。

    finally

    在进行异常的处理之后,在异常的处理格式中还有一个finally语句,那么此语句将作为异常的统一出口,不管是否产生了异常,最终都要执行此段代码。

    异常体系结构

    异常指的是Exception , Exception类, 在Java中存在一个父类Throwable(可能的抛出) Throwable存在两个子类: 1.Error:表示的是错误,是JVM发出的错误操作,只能尽量避免,无法用代码处理。 2.Exception:一般表示所有程序中的错误,所以一般在程序中将进行try…catch的处理。 多异常捕获的注意点: 1、 捕获更粗的异常不能放在捕获更细的异常之前。 2、 如果为了方便,则可以将所有的异常都使用Exception进行捕获。 特殊的多异常捕获写法: catch(异常类型1 |异常类型2 对象名){ //表示此块用于处理异常类型1 和 异常类型2 的异常信息 }

    throws关键字

    在程序中异常的基本处理已经掌握了,但是随异常一起的还有一个称为throws关键字,此关键字主要在方法的声明上使 用,表示方法中不处理异常,而交给调用处处理。 格式: 返回值 方法名称()throws Exception{ }

    throw关键字

    throw关键字表示在程序中人为的抛出一个异常,因为从异常处理机制来看,所有的异常一旦产生之后,实际上抛出的就是一个异常类的实例化对象,那么此对象也可以由throw直接抛出。 代码: throw new Exception(“抛着玩的。”)

    RuntimeExcepion与Exception的区别

    注意观察如下方法的源码: Integer类: public static int parseInt(String text)throws NumberFormatException 此方法抛出了异常, 但是使用时却不需要进行try。。。catch捕获处理,原因: 因为NumberFormatException并不是Exception的直接子类,而是RuntimeException的子类,只要是 RuntimeException的子类,则表示程序在操作的时候可以不必使用try…catch进行处理,如果有异常发生,则由JVM进行处理。当然,也可以通过try catch处理。

    自定义异常类 了解

    编写一个类, 继承Exception,并重写一参构造方法 即可完成自定义受检异常类型。 编写一个类, 继承RuntimeExcepion,并重写一参构造方法 即可完成自定义运行时异常类型。 例如: class MyException extends Exception{ // 继承Exception,表示一个自定义异常类 public MyException(String msg){ super(msg) ; // 调用Exception中有一个参数的构造 } }; 自定义异常可以做很多事情, 例如: class MyException extends Exception{ public MyException(String msg){ super(msg) ; //在这里给维护人员发短信或邮件, 告知程序出现了BUG。 } };

    异常处理常见面试题

    1. try-catch-finally 中哪个部分可以省略? 答: catchfinally可以省略其中一个 , catchfinally不能同时省略 注意:格式上允许省略catch, 但是发生异常时就不会捕获异常了,我们在开发中也不会这样去写代码. 2. try-catch-finally 中,如果 catchreturn 了,finally 还会执行吗? 答:finally中的代码会执行 详解: 执行流程: 1. 先计算返回值, 并将返回值存储起来, 等待返回 2. 执行finally代码块 3. 将之前存储的返回值, 返回出去; 需注意: 1. 返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不 会改变 2. finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是trycatch中的值 3. 如果在trycatch中停止了JVM,finally不会执行.例如停电- -, 或通过如下代码退出 JVM:System.exit(0);

    例题:

    快递柜

    bean package com.java.demo1.bean; import java.util.Objects; public class Express { private String id; private String company; private int code; public Express() { } public Express(String id, String company, int code) { this.id = id; this.company = company; this.code = code; } public String getId() { return id; } public String getCompany() { return company; } public int getCode() { return code; } public void setId(String id) { this.id = id; } public void setCompany(String company) { this.company = company; } public void setCode(int code) { this.code = code; } @Override public String toString() { return "Express{" + "id='" + id + '\'' + ", company='" + company + '\'' + ", code=" + code + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Express express = (Express) o; return Objects.equals(id, express.id); } @Override public int hashCode() { return Objects.hash(id); } } dao package com.java.demo1.dao; import com.java.demo1.bean.Express; import java.util.Random; public class Dao { private Express[][] expresses = new Express[10][10]; private int size = 0; private int x; private int y; //数据录入 public boolean insert(Express e){ if(size<100){ while(true){ x = (int)(new Random().nextInt(10)); y = (int)(new Random().nextInt(10)); if(expresses[x][y]==null){ expresses[x][y] = e; size++; return true; } } } return false; } //数据删除 public boolean delete(Express e){ for (int i=0;i<10;i++){ for (int j=0;j<10;j++){ if(expresses[i][j]==e){ expresses[i][j] = null; size--; return true; } } } return false; } //数据修改 public boolean updata(Express e,Express e2){ for (int i=0;i<10;i++){ for (int j=0;j<10;j++){ if(expresses[i][j]==e){ expresses[i][j] = e2; return true; } } } return false; } //获取所有数据 public Express[][] getAll(){ return expresses; } //数据查询 public Express getByNumber(String number){ Express e = new Express(); e.setId(number); for (int i=0;i<10;i++){ for (int j=0;j<10;j++){ if(e.equals(expresses[i][j])){ return expresses[i][j]; } } } return null; } public Express getByCode(int code){ for (int i=0;i<10;i++){ for (int j=0;j<10;j++){ if(expresses[i][j]!=null){ if(expresses[i][j].getCode()==code){ return expresses[i][j]; } } } } return null; } //数组判空 public boolean size() { if (size==0){ return false; } return true; } } main package com.java.demo1.main; import com.java.demo1.bean.Express; import com.java.demo1.dao.Dao; import com.java.demo1.view.Views; public class Main { private static Dao dao; private static Views view; //main函数 public static void main(String[] args){ init(); view.start(); login(); view.end(); } //初始化 public static void init(){ dao = new Dao(); view = new Views(); } //权限选择 public static void login(){ o:while(true){ int num = -1; num = view.login(); switch (num){ case 0: break o; case 1: aindex(); break; case 2: uindex(); break; default: view.choiceError(); break; } } } //管理员界面 public static void aindex(){ p:while(true){ int num = -1; num = view.aindex(); switch (num){ case 0: break p; case 1: insert(); break; case 2: delete(); break; case 3: updata(); break; case 4: printAll(); break; default: view.choiceError(); break; } } } //快递录入 public static void insert(){ Express e = view.insert(); if (dao.getByNumber(e.getId())!=null) { view.youle(); } else { if(dao.insert(e)){ view.printInsert(); view.printExpress(e); }else{ view.insertError(); } } } //快递删除 public static void delete(){ String id = view.delete(); Express e = dao.getByNumber(id); if(e!=null){ int yon = view.deleteConfirm(); switch (yon){ case 1: if(dao.delete(e)){ view.printDelete(); view.deleteCode(e.getCode()); }else{ view.deleteError(); } break; case 2: break; default: view.choiceError(); break; } }else{ view.error(); } } //快递修改 public static void updata(){ String id = view.update(); Express e = dao.getByNumber(id); if(e!=null){ view.printExpress(e); Express e2 = view.newData(); if(dao.updata(e,e2)){ view.printUpdata(); view.deleteCode(e.getCode()); }else{ view.updataError(); } }else{ view.error(); } } //查询所有快递 private static void printAll() { Express[][] expresses = dao.getAll(); if(dao.size()){ view.printAll(expresses); }else { view.nullExpress(); } } //用户界面 public static void uindex(){ q:while(true){ int num = view.uindex(); switch (num){ case 0: break q; case 1: int code = view.getExpress(); Express e = dao.getByCode(code); if(e!=null){ if(dao.delete(e)){ view.printGet(); view.deleteCode(e.getCode()); }else{ view.getError(); } }else{ view.error(); } break; default: view.choiceError(); break; } } } } views package com.java.demo1.view; import com.java.demo1.bean.Express; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Scanner; public class Views { private Scanner input = new Scanner(System.in); private Random rand = new Random(); private List<Integer> list = new ArrayList<Integer>(); //开始 public void start(){ System.out.println("---欢迎使用---"); } //结束 public void end(){ System.out.println("---感谢您的使用---"); System.out.println("-------再见-------"); } //接受用户输入的选项 public int input(){ while(true){ int num = -1; try { num = input.nextInt(); return num; }catch(Exception e){ System.out.println("请正确输入序号!!!"); input.next(); } } } //打印信息 public void printExpress(Express e){ System.out.println("快递单号:"+e.getId()+", 快递公司:"+e.getCompany()+", 快递取件码:"+e.getCode()); } //输入信息有误 public void error(){ System.out.println("你输入的信息有误,快递不存在,请重新输入"); } //输入选项有误 public void choiceError(){ System.out.println("你输入的选项有误,请重新输入"); } //空快递库 public void nullExpress(){ System.out.println("当前快递库为空"); } //随机生成取件码 public int code(){ while(true){ int chongfu = 0; int code = (int)(rand.nextInt(900000)+100000); for(int i=0;i<list.size();i++){ if(list.get(i)==code){ chongfu++; } } if(chongfu==0){ list.add(code); return code; } } } //登录 public int login(){ System.out.println("---请选择登陆用户---"); System.out.println("---1.管理员登录-----"); System.out.println("---2.用户登录-------"); System.out.println("---0.退出-----------"); return input(); } //管理员页面 public int aindex(){ System.out.println("---请选择要进行的操作---"); System.out.println("---1.快递录入----------"); System.out.println("---2.删除快递----------"); System.out.println("---3.修改快递----------"); System.out.println("---4.查看所有快递------"); System.out.println("---0.返回上级目录------"); return input(); } //快递录入 public Express insert(){ System.out.println("---请输入快递单号---"); String number = input.next(); System.out.println("---请输入快递公司---"); String company = input.next(); int code = code(); Express e = new Express(); e.setId(number); e.setCompany(company); e.setCode(code); return e; } //重复录入 public void youle(){ System.out.println("快递已存在"); } //录入成功 public void printInsert(){ System.out.println("快递录入成功"); } //录入失败 public void insertError(){ System.out.println("快递录入失败"); } //快递删除 public String delete(){ System.out.println("---请输入需要删除的快递单号---"); String number = input.next(); return number; } //删除确认 public int deleteConfirm(){ System.out.println("---是否确认删除该快递---"); System.out.println("---1.是---------------"); System.out.println("---2.否---------------"); return input(); } //删除成功 public void printDelete(){ System.out.println("快递删除成功"); } //删除失败 public void deleteError(){ System.out.println("快递删除失败"); } //修改快递 public String update(){ System.out.println("---请输入需要修改的快递单号---"); String number = input.next(); return number; } //新的数据 public Express newData(){ System.out.println("---请输入新的快递单号---"); String number = input.next(); System.out.println("---请输入新的快递公司---"); String company = input.next(); int code = code(); Express e = new Express(); e.setId(number); e.setCompany(company); e.setCode(code); return e; } //修改成功 public void printUpdata(){ System.out.println("快递修改成功"); } //修改失败 public void updataError(){ System.out.println("快递修改失败"); } //查询所有快递 public void printAll(Express[][] e){ for(int i=0;i<10;i++){ for(int j=0;j<10;j++){ if(e[i][j]!=null){ printExpress(e[i][j]); } } } } //用户页面 public int uindex(){ System.out.println("---请选择要进行的操作---"); System.out.println("---1.快递取出----------"); System.out.println("---0.返回上级目录------"); return input(); } //取快递 public int getExpress(){ System.out.println("---请输入取件码---"); return input(); } //删除取件码 public void deleteCode(int code){ list.remove((Integer) code); } //取件成功 public void printGet(){ System.out.println("取件成功"); } //取件失败 public void getError(){ System.out.println("取件失败"); } }
    Processed: 0.011, SQL: 8