1. 异常是指在程序的运行过程中所发生的不正常的情况或者发生错误,导致中断正在运行的程序。
2. 异常处理语句:try - catch, 如果try代码块中捕获到异常,则到catch代码块中处理,否则跳过忽略catch代码块。(良好的编程习惯,在异常捕获机制的最后书写catch(Exception e)(父类,顶极异常)捕获未知的错误);
1 try{ 2 //关键字,只能有一个try语句可能发生异常的代码片段 3 4 }catch(Exception e){ 5 //列举代码中可能出现的异常类型,可有多个catch语句当出现了列举的异常类型后,在这里处理,并有针对性的处理 6 }
3. Exception 根据是否处理分为两种情况。
1)RuntimeException:运行时异常。不要求程序必须做出处理。是所有运行时异常的父类。
2)CheckedException:检查时异常。要求程序必须处理,不处理编译不通过。
1 public class Test01 { 2 public static void main(String[] args) { 3 // 运行时异常 4 Scanner sc = new Scanner(System.in); 5 // runtime exception 6 int r = sc.nextInt(); 7 System.out.println("r = "+ r); 8 9 // 检查时异常 10 SimpleDateFormat df = new SimpleDateFormat(); 11 try { 12 Date date = df.parse("2019"); 13 } catch (ParseException e) { 14 e.printStackTrace(); 15 } 16 } 17 }
3)finally块:finally块定义在catch块的最后(所有catch最后),且只能出现一次(0-1次), 无论程序是否出错都会执行的块! 无条件执行!通常在finally语句中进行资源的消除工作,如关闭打开的文件,删除临时文件等。
finally 总是执行,常用进行收尾类工作。
1 public static void main(String[] args) { 2 Scanner sc = new Scanner(System.in); 3 System.out.println("请输入第一个数:"); 4 5 int num1 = 0; 6 int num2 = 0; 7 8 try { 9 num1 = sc.nextInt(); 10 11 System.out.println("请输入第二个数:"); 12 num2 = sc.nextInt(); 13 14 int r = num1 / num2; 15 System.out.println("num1/num2 = " + r); 16 } catch (Exception e) { 17 System.out.println("程序出现异常"); 18 } finally { 19 System.out.println("不管是否出现异常,finally都执行"); 20 } 21 22 System.out.println("程序正常结束");
特殊情况:
[1] finally不执行的情况:System.exit(0) 正常推出jvm,finally不会执行。
[2]catch可以省略,变成try…finally块。
4. 常见的运行时异常
ArithmeticException:数学计算异常。比如除数为0
InputMismatchException:输入不匹配异常
ArrayIndexOutofBoundsException:数组下标越界异常。
NullPointException:空指针异常,对象没有初始化就使用时,jvm会抛出该异常
IllegalArgumentException:非法参数异常。
ClassCastException:强制类型转换异常。
NumberFormatException:数字格式化异常。比如把“abc”格式化成数字。
常见的检查时异常:
ClassNotFoundException:类没有被发现异常。
SQLException:数据库相关异常
IOException:IO操作异常
ParseException:解析错误异常
FileNotFoundException:文件未发现异常。
5. 运行时异常和检查时异常的区别
运行时异常:包括RuntimeException及其所有子类。不要求程序必须对它们作出处理,即使没有使用try-catch或throws进行处理,仍旧可以进行编译和运行。如果运行时发生异常,会输出异常的堆栈信息并中止程序执行。常见的运行时异常有: NullPointerException、IllegalArgumentException、ClassCastException、NumberFormatException、ArrayIndexOutOfBoundsException、ArithmeticException;
Checked异常(非运行时异常):编译时检查,除了运行时异常外的其他异常类都是Checked(都是可检查异常)异常。程序必须捕获或者声明抛出这种异常,否则出现编译错误,无法通过编译。处理方式包括两种:通过try-catch捕获异常,通过throws声明抛出异常从而交给上一级调用方法处理。
6. throw关键字:用于主动抛出一个异常
除了系统自动抛出异常外,有些问题需要开发者手动抛出异常,通知调用方法去解决时,会将这个错误告知外界,而告知外界的方式就是throw异常(抛出异常)catch语句中也可抛出异常。方法通常有参数,调用者在调用我们的方法帮助解决问题时,通常会传入参数,若我们方法的逻辑是因为参数的错误而引发的异常,应该抛出,若是我们自身的原因应该自己处理。
1 2 public class Student { 3 private String name; 4 private String gender; 5 6 public String getName() { 7 return name; 8 } 9 10 public void setName(String name) { 11 this.name = name; 12 } 13 14 public String getGender() { 15 return gender; 16 } 17 18 public void setGender(String gender) throws Exception{ 19 if(gender.equals("男") || gender.equals("女")) { 20 this.gender = gender; 21 }else { 22 throw new Exception("性别不合法!"); 23 } 24 } 25 26 public Student(String name, String gender) { 27 super(); 28 this.name = name; 29 this.gender = gender; 30 } 31 32 public Student() { 33 super(); 34 } 35 }
1 public class Test01 { 2 public static void main(String[] args){ 3 Student stu = new Student(); 4 stu.setName("二哈"); 5 try { 6 stu.setGender("xxx"); 7 } catch (Exception e) { 8 System.out.println(e.getMessage()); 9 } 10 } 11 }
7. throws关键字
当一个方法可能存在异常,而此时自身又无法更好的处理,可以交给外界处理。此时用throws声明并抛出异常。
开发者可以根据需要声明检查时异常(Exception或者非运行时异常)和运行时异常(RuntimeException或其子类),如果调用处也不知道如何处理异常,可选择继续声明异常,我们把这个过程称为异常上抛。
1 public class Test01 { 2 3 public static int div(int a, int b) throws Exception{ 4 int r = 0; 5 r = a / b; 6 return r; 7 } 8 9 public static void main(String[] args) throws Exception{ 10 11 //【1】 调用处知道如何处理! 12 /* 13 try { 14 Test01.div(10, 0); 15 } catch (Exception e) { 16 e.printStackTrace(); 17 } 18 */ 19 20 // 【2】调用处也不知道如何处理 21 Test01.div(10, 0); 22 23 } 24 }
注意事项:
注意throw和throws关键字的区别:抛出异常和声明抛出异常。
不能在main方法上throws,因为调用者JVM直接关闭程序。