前言
基于分支判断可以处理掉异常,但是会有以下几个问题。
package Exception; import java.util.Scanner; public class Test01 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入第1个数字:"); if (sc.hasNextInt()) { int num1 = sc.nextInt(); System.out.print("请输入第2个数字:"); if (sc.hasNextInt()) { int num2 = sc.nextInt(); if (num2 == 0) { System.out.println("数字2不能为0"); } else { System.out.printf("%d 除以 %d = %d\n", num1, num2, num1 / num2); } } else { System.out.println("数字2输入错误"); } } else { System.out.println("数字1输入错误"); } } }
- 业务代码和处理异常的代码混在一起,代码就会变得臃肿
- 代码可读性差
- 程序员需要花费大量的经历来维护这个漏洞
Java的异常怎么看?
程序难免出现异常,程序员要做的是通过程序抛出的异常,快速定位问题,然后解决它。
我刚开始写代码的时候,一旦程序抛出异常,第一反应是不断检查自己的代码,其实解决问题的切入点应该是先看懂异常。
try catch异常捕获
我们可以通过 try catch捕获异常,当我们捕获到异常之后,可以做以下处理;
package Exception; import java.util.Scanner; public class Test01 { public static void main(String[] args) { try { Scanner sc = new Scanner(System.in); System.out.print("请输入第1个数字:"); int num1 = sc.nextInt(); System.out.print("请输入第2个数字:"); int num2 = sc.nextInt(); System.out.printf("%d 除以 %d = %d\n", num1, num2, num1 / num2); } catch (Exception e) { //处理方式1:不处理 //处理方式2:面向用户做友好提示 //处理方式3:面向程序员 //3.1:显示异常的类型 System.out.println(e.toString()); //3.1:显示异常描述信息,若无返回null System.out.println(e.getMessage()); //3.2:显示异常堆栈信息 e.printStackTrace(); //处理方式3:抛出异常,程序被中断 throw e; } System.out.println("程序结束!"); } }
catch多种异常
如果我们的代码会出现多种不同的异常,就需要写很多catch语句,这样就会增加了代码量导致代码的可阅读性很差。
在JDK 1.7之后我们可以通过 | ,一次捕获到多种不同类型的异常。
package Exception; import java.util.InputMismatchException; import java.util.Scanner; public class Test01 { public static void main(String[] args) { try { Scanner sc = new Scanner(System.in); System.out.print("请输入第1个数字:"); int num1 = sc.nextInt(); System.out.print("请输入第2个数字:"); int num2 = sc.nextInt(); System.out.printf("%d 除以 %d = %d\n", num1, num2, num1 / num2); //同时捕获多种不同异常,但是这些异常之间必须没有任何交集。 } catch (ArithmeticException | InputMismatchException e) { System.out.println(e); } catch (Exception e) { System.out.printf("异常信息%s\n", e.toString()); } finally { System.out.println("程序结束!"); } } }
finally关键字
finally中的代码,无论程序是否遇到异常甚至return,都会执行,所以finally可以用于释放socket资源。
但是如果执行了System.exit(0),终止当前虚拟机,finally将不会执行;
执行的优先顺序是:System.exit(0)--->return--->finally。
package Exception; import java.util.Scanner; public class Test01 { public static void main(String[] args) { try { Scanner sc = new Scanner(System.in); System.out.print("请输入第1个数字:"); int num1 = sc.nextInt(); System.out.print("请输入第2个数字:"); int num2 = sc.nextInt(); System.out.printf("%d 除以 %d = %d\n", num1, num2, num1 / num2); System.exit(0); //终止当前虚拟机执行 return; } catch (Exception e) { } finally { System.out.println("关键"); } System.out.println("程序结束!"); } }
throw和throws抛出异常
有时候我们需要主动抛出异常,让调用者解决。
package Exception; import java.util.InputMismatchException; import java.util.Scanner; public class Test01 { //2.调用者不处理,可以继续throws 抛出异常,给调用者解决; public static void main(String[] args) throws ArithmeticException { devide(); } public static void devide() throws ArithmeticException { Scanner sc = new Scanner(System.in); System.out.print("请输入第1个数字:"); int num1 = sc.nextInt(); System.out.print("请输入第2个数字:"); int num2 = sc.nextInt(); if (num2 == 0) { //1.主动抛出1个异常,让调用者处理; throw new ArithmeticException(); } System.out.printf("%d 除以 %d = %d\n", num1, num2, num1 / num2); } }
具有继承关系的类如何抛出异常?
当子类重写父类的方法时,子类抛出的异常必须是父类抛出异常的子类,或者平级。
自定义异常
我们可以通过继承的方式,自定义异常类;
package Exception; public class MyException extends RuntimeException { static final long serialVersionUID = -70348971907459L; public MyException() { } public MyException(String msg) { super(msg); } } class TestException { public static void main(String[] args) { throw new MyException("我自定义的异常信息"); } }
自动关闭资源
我们使用try-with-resource语句,可以try块退出时自动调用res.close()方法,关闭资源;
package com.test; import com.sun.xml.internal.ws.api.message.HeaderList; import com.test.entity.Staffs; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.FileInputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class Main { public static void main(String[] args) throws Exception { try (SqlSession session=MybatisUtil.getsession(true)){ Staffs staff3=session.selectOne("selectOne",3); System.out.println(staff3.getUsername()); } } }
参考