# 1 - 异常
# 1.1 - 基本概念
异常,指不正常,在Java中异常处理机制能让程序在异常情况发生时按照事先设定好的逻辑方式去有针对性的处理异常的方式。
# 1.2 - 异常的主要分类
java.lang.Throwable 类 java 中所有错误和异常的超类,已知直接子类有 Error 类和 Exception 类。
名称 |
说明 |
RuntimeException |
运行时异常,也叫作非检测性异常 |
IOException |
IO 异常类,也叫作检测性异常 |
RuntimeException 主要子类
异常类型 |
说明 |
ArithmeticException |
算数异常 |
ArrayIndexOutofBoundsException |
数组下标越界异常 |
NullPoniterException |
空指针异常 |
ClassCastException |
类型转换异常 |
NumberFormatException |
数字格式异常 |
注意:
当程序执行过程中产生异常并没有手动处理时,则采用默认的处理方式,打印异常名称、异常原因、异常的位置等信息,并终止程序,导致后续代码无法运行。
运行时异常的处理
绝大多数的运行时异常都可以通过if判断的形式将其避免发生。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import java.io.IOException;
public class Demo02 { public static void main(String[] args) { int a = 10; int b = 0;
int[] arr = new int[5]; int pos = 5; if (pos < 5 && pos >= 0){ System.out.println(arr[pos]); }
String s1 = null; if (s1 != null){ System.out.println(s1.length()); }
Exception e = new Exception(); if (e instanceof IOException){ IOException e1 = (IOException) e; }
String s2 = "123abc"; if (s2.matches("\\d+")){ System.out.println(Integer.parseInt(s2)); } } }
|
# 1.3 - 异常的捕获格式
1 2 3 4 5
| try{ 编写可能会产生异常的语句; }catch(异常类型 变量名){ 编写针对该异常的处理语句; }
|
# 1.4 - 异常的捕获以及执行流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import java.io.FileInputStream; import java.io.FileNotFoundException;
public class Demo03 { public static void main(String[] args) { try { System.out.println("a"); FileInputStream fis = new FileInputStream("./a.txt"); System.out.println("b"); }catch (FileNotFoundException e){ e.printStackTrace(); System.out.println("c"); }finally { System.out.println("d"); }
System.out.println("e");
} }
|
当上述代码没有发生异常时的执行流程是:a b d e
当上述代码发生异常时的执行流程是: a c d e
finally 中通常编写无异常是否发生都应该执行的代码,因此通常来做善后处理,比如:关闭文件,断开数据库连接等操作
注意事项
当需要 catch 多种不同类型的异常时,切记晓得类型需要放在大的类型的上面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;
public class Demo05 { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("./aa.txt"); fis.close(); }
catch (Exception e){ e.printStackTrace(); } } }
|
# 1.5 - 手动抛出异常
在某些特殊的场合中,对于出现的异常无法直接处理或者不便于处理时,就可以选择将异常转移给方法的调用者,这种形式就叫做异常的抛出。
语法格式:
1
| public void show() throws IOException{方法体}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import java.io.FileInputStream; import java.io.FileNotFoundException;
public class Demo06 { private static void show() throws FileNotFoundException { FileInputStream fis = new FileInputStream("./a.txt"); }
public static void main(String[] args) { try { show(); } catch (FileNotFoundException e) { e.printStackTrace(); }
} }
|
在子类中,如果父类中被重写的方法抛出了异常,那么子类中重写的方法可以抛出更小的异常、一样的异常,不可以抛出更大的异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import java.io.IOException;
public class Demo07 { public void show() throws IOException{ System.out.println("我是Demo07中的show方法"); } } -------------------------------------------------------- import java.io.FileNotFoundException; import java.io.IOException;
public class Demo07Sub extends Demo07{
}
|
# 1.6 - 自定义异常
自定义异常类去继承于Exception类或其子类,提供两个版本的构造器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
public class AgeException extends Exception{ public AgeException() { }
public AgeException(String message) { super(message); } } ------------------------------------------
public class Student { private String name; private int age;
public Student() { }
public Student(String name, int age) { setName(name); try { setAge(age); } catch (AgeException e) { e.printStackTrace(); } }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) throws AgeException { if(age < 0 || age > 150){ throw new AgeException("年龄不合理,请重新输入!"); }else{ this.age = age; }
}
@Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } ------------------------------------------------------------
public class Demo08 { public static void main(String[] args) { Student stu = new Student("Andy", -18); System.out.println(stu); } }
|
# 1.7 - final、finally、finalize 的区别
方法名 |
说明 |
final |
修饰的变量不可被修改,方法不可被重写,类不可被继承 |
finally |
异常处理机制中的一个关键字 |
finalize |
垃圾收集器执行之前被调用的方法 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class Demo01 { public final static String NAME = "Andy";
public final void show(){ System.out.println("我是被final修饰的方法"); }
@Override protected void finalize() throws Throwable { System.out.println("我被调用了"); }
public static void main(String[] args) {
Demo01 demo01 = new Demo01(); demo01 = null; System.gc(); } } -------------------------------
public class Demo01Sub extends Demo01{
}
|