异常

1.异常处理

1.1 try -catch

try 尝试 表示将可能出现异常的代码 存放在try中 try不能单独出现 必须结合catch 或者 finally catch 捕获 表示捕获对应的异常 在catch代码块中处理

情况1: 捕获的是InputMismatchException 出现的也是InputMismatchException 可以捕获到异常 不会中断程序

  1. public class Test2 {
  2. public static void main(String[] args) {
  3. try {
  4. Scanner in = new Scanner(System.in);
  5. System.out.print("请输入被除数:");
  6. int num1 = in.nextInt();
  7. System.out.print("请输入除数:");
  8. int num2 = in.nextInt();
  9. System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
  10. }catch(InputMismatchException e) {
  11. e.printStackTrace();
  12. // System.err.println("异常捕获到了,出现了输入不匹配异常");
  13. }
  14. System.out.println("感谢使用本程序!");
  15. }
  16. }

情况2:出现的异常和捕获的异常不同 依然会中断程序

  1. public class Test3 {
  2. public static void main(String[] args) {
  3. try {
  4. Scanner in = new Scanner(System.in);
  5. System.out.print("请输入被除数:");
  6. int num1 = in.nextInt();
  7. System.out.print("请输入除数:");
  8. int num2 = in.nextInt();
  9. System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
  10. }catch(InputMismatchException e) {
  11. e.printStackTrace();
  12. // System.err.println("异常捕获到了,出现了输入不匹配异常");
  13. }
  14. System.out.println("感谢使用本程序!");
  15. }
  16. }

情况3:如果一段代码中有可能出现多个异常 我们可以使用多个catch块处理

  1. public class Test4 {
  2. public static void main(String[] args) {
  3. try {
  4. Scanner in = new Scanner(System.in);
  5. System.out.print("请输入被除数:");
  6. int num1 = in.nextInt();
  7. System.out.print("请输入除数:");
  8. int num2 = in.nextInt();
  9. System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
  10. }catch(InputMismatchException e) {
  11. e.printStackTrace();
  12. // System.err.println("异常捕获到了,出现了输入不匹配异常");
  13. }catch(ArithmeticException e) {
  14. e.printStackTrace();
  15. System.err.println(e.getMessage());
  16. }
  17. System.out.println("感谢使用本程序!");
  18. }
  19. }

情况4: 我们可以统一写一个异常父类 来处理所有的异常 异常catch块书写顺序 先子类 后父类

  1. public class Test5 {
  2. public static void main(String[] args) {
  3. try {
  4. Scanner in = new Scanner(System.in);
  5. System.out.print("请输入被除数:");
  6. int num1 = in.nextInt();
  7. System.out.print("请输入除数:");
  8. int num2 = in.nextInt();
  9. System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
  10. }catch(InputMismatchException e) {
  11. e.printStackTrace();
  12. }catch(ArithmeticException e) {
  13. e.printStackTrace();
  14. }catch(Exception e) {
  15. e.printStackTrace();
  16. }
  17. System.out.println("感谢使用本程序!");
  18. }
  19. }

1.2 finally

finally 表示最终的意思 表示最终不管 是否出现异常 以及异常是否被捕获到 都将执行的代码 finally不能单独出现 必须结合try 或者 try -catch

  1. public class Test1 {
  2. public static void main(String[] args) {
  3. try {
  4. Scanner in = new Scanner(System.in);
  5. System.out.print("请输入被除数:");
  6. int num1 = in.nextInt();
  7. System.out.print("请输入除数:");
  8. int num2 = in.nextInt();
  9. System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
  10. }catch(InputMismatchException e) {
  11. e.printStackTrace();
  12. }finally {
  13. System.out.println("感谢使用本程序!");
  14. }
  15. }
  16. }

finally不执行的唯一情况 :在finally执行之前退出JVM虚拟机 System.exit(int status); 状态码 0表示 正常退出 非0表示非正常退出 目前写哪个数值都可以退出 没有任何区别

  1. public class Test2 {
  2. public static void main(String[] args) {
  3. try {
  4. Scanner in = new Scanner(System.in);
  5. System.out.print("请输入被除数:");
  6. int num1 = in.nextInt();
  7. System.out.print("请输入除数:");
  8. int num2 = in.nextInt();
  9. System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
  10. System.exit(1);
  11. }catch(InputMismatchException e) {
  12. e.printStackTrace();
  13. }finally {
  14. System.out.println("感谢使用本程序!");
  15. }
  16. }
  17. }

finally结合try使用

  1. package com.qfedu.test2;
  2. import java.util.Scanner;
  3. /**
  4. * finally结合try使用
  5. * @author WHD
  6. *
  7. */
  8. public class Test3 {
  9. public static void main(String[] args) {
  10. try {
  11. Scanner in = new Scanner(System.in);
  12. System.out.print("请输入被除数:");
  13. int num1 = in.nextInt();
  14. System.out.print("请输入除数:");
  15. int num2 = in.nextInt();
  16. System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
  17. }finally {
  18. System.out.println("感谢使用,程序结束");
  19. }
  20. }
  21. }

以下代码 在finally中对返回值的操作 不会影响返回值 实际开发中 不推荐在finally中对返回值做操作 执行顺序:先执行try中return 再执行finally 最后再次执行finally中的return 还使用最初确定的返回值

  1. package com.qfedu.test3;
  2. /**
  3. * 以下代码 在finally中对返回值的操作 不会影响返回值
  4. * 实际开发中 不推荐在finally中对返回值做操作
  5. *
  6. * 执行顺序:先执行try中return 再执行finally 最后再次执行finally中的return
  7. * 还使用最初确定的返回值
  8. * @author WHD
  9. *
  10. */
  11. public class Test1 {
  12. public static void main(String[] args) {
  13. System.out.println(m1());
  14. }
  15. public static int m1() {
  16. int num = 10;
  17. try {
  18. num ++;
  19. return num;
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }finally {
  23. num ++;
  24. }
  25. return num;
  26. }
  27. }

1.3 throw和throws

throw表示抛出异常 抛出的异常分为两大类: 1.检查异常CheckedException 调用者必须处理 要么try-catch 要么继续往后声明 2.运行时异常RuntimeException 调用者不是必须处理 throws表示声明异常

  1. package com.qfedu.test4;
  2. import java.io.FileNotFoundException;
  3. /**
  4. * throw throws
  5. * 生成并抛出异常 声明方法内抛出了异常
  6. 位于方法体内部,可作为单独语句使用 必须跟在方法参数列表后面,不能单独使用
  7. 抛出一个异常对象,且只能是一个 声明抛出异常类型,可以跟多个异常(逗号分隔)
  8. * @author WHD
  9. *
  10. */
  11. public class Test2 {
  12. public static void main(String[] args) throws ClassNotFoundException, FileNotFoundException {
  13. m1(10);
  14. m2(10);
  15. }
  16. public static void m1(int num){
  17. if(num % 3 == 1) {
  18. throw new ClassCastException("类转换异常");
  19. // System.out.println(); 不可达代码
  20. }else {
  21. throw new ArithmeticException("算数运算异常");
  22. }
  23. }
  24. public static void m2(int num) throws ClassNotFoundException, FileNotFoundException {
  25. if(num % 3 == 1) {
  26. throw new ClassNotFoundException("类没有找到");
  27. }else {
  28. throw new FileNotFoundException("文件没有找到");
  29. }
  30. }
  31. }

2. 自定义异常

当JDK 中的异常类型不能满足程序的需要时,可以自定义异常类
使用自定义异常的步骤

  1. package com.qfedu.test5;
  2. public class Student {
  3. private String name;
  4. private int age;
  5. private String sex;
  6. public String getSex() {
  7. return sex;
  8. }
  9. public void setSex(String sex) {
  10. if(sex.equals("男") || sex.equals("女")) {
  11. this.sex = sex;
  12. }else {
  13. throw new SexNotFoundException("sex error!");
  14. }
  15. }
  16. // alt + s + r
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public int getAge() {
  24. return age;
  25. }
  26. public void setAge(int age) throws InputAgeException {
  27. if(age >= 0 && age <= 130) {
  28. this.age = age;
  29. }else {
  30. throw new InputAgeException("年龄不合适");
  31. }
  32. }
  33. public static void main(String[] args) {
  34. Student stu = new Student();
  35. stu.setName("赵四");
  36. try {
  37. stu.setAge(130);
  38. } catch (InputAgeException e) {
  39. e.printStackTrace();
  40. }
  41. stu.setSex("母");
  42. }
  43. }
  1. package com.qfedu.test5;
  2. public class InputAgeException extends Exception{
  3. private static final long serialVersionUID = -5819204170683788513L;
  4. public InputAgeException(String message) {
  5. super(message);
  6. }
  7. }
  1. package com.qfedu.test5;
  2. public class SexNotFoundException extends RuntimeException{
  3. private static final long serialVersionUID = 1L;
  4. // alt + s 选择从父类生成构造方法
  5. public SexNotFoundException(String message) {
  6. super(message);
  7. }
  8. }