异常
异常的分类
java.lang.Throwable (顶级父类)
|——Error——————一般不编写针对性的代码进行处理
|——Exception——————可以进行异常处理
|——checked(编译时异常)
|——IOException
|——FileNotFoundException
|——ClassNotFoundException
|——unchecked(运行时异常)
|——NullpointerException
|——ArrayIndexOutOFBoundsException
|——ClassCastException
|——-NumberFormatException
|——InputMismatchException
|——ArithmeticException
运行时异常举例
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
|
public class ExceptionTest { @Test public void test1(){ int[] arr = null; System.out.println(arr[3]);
String str = null; System.out.println(str.charAt(0)); }
@Test public void test2(){ int[] arr = new int[10]; System.out.println(arr[10]); }
@Test public void test3(){ Object obj = new Date(); String str = (String)obj; }
@Test public void test4(){ String str = "abc"; int a= Integer.parseInt(str); }
@Test public void test5(){ Scanner scsn = new Scanner(System.in); int score = scsn.nextInt(); System.out.println(score);
}
@Test public void test6(){ int a = 5 / 0; System.out.println(a); } }
|
编译时异常
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Test public void test7(){ FileInputStream fileInputStream = new FileInputStream(new File("hello.txt"));
int i;
while((i= fileInputStream.read()) != -1){ System.out.println(i); }
fileInputStream.close(); }
|
异常处理
抓抛模型
过程一 : ”抛“ —— 程序执行过程中,一大发现异常就会在异常代码出生成一个对应异常类的对象,并将此对象抛出。
一旦抛出对象,其后代码不在执行。
过程二 : ”抓“ —— 抓可以理解为异常处理的方式 ①try - catch - finally ② Throws
try - catch - finally的使用
==try{==
==可能出现异常的代码;==
==}catch (异常类型1 变量名1){==
==处理异常的方式1;==
==} catch (异常类型2 变量名2){==
==处理异常的方式2;==
==} catch (异常类型3 变量名3){==
==处理异常的方式3;==
==}==
==…==
==finally{==
==一定会执行的代码;==
==}==
finally 是可选的
使用try将可能出现异常的代码包裹起来,在执行过程中,一旦出现异常,就会生成一个对应的异常类对象,根据此对象的类型去catch中匹配
一旦try中的异常匹配到某一个catch,就进入catch中进行异常处理,一旦处理完成,就跳出当前try - catch结构(没有finally),继续执行
catch中的异常类型如果没有子父类关系,则谁在上谁在下没有无所谓;==如果满足子父关系,则子类必须在父类上边==
常用的异常处理方法:
① ==String getMessage()== 返回异常信息
② ==printStackTrace()==
在 try 中声明的变量,在 try 外边不能使用
finally 中的代码一定会被执行,即使 catch 中又出现异常,try 中有return 或者 catch 中有 return 语句 finally 中的代码也会被执行。
体会1:try - catch - finally 处理编译时异常,是程序编译时不报错,但是运行时仍然可能报错。相当于使用try - catch - finally结构将 一个编译时异常延迟到运行时。
体会2:开发中,由于运行时异常比较常见,所以通常就不针对运行时异常 try - catch - finally 处理,针对编译时异常,一定要进行异 常处理。
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void test1(){ String str = "123"; str = "abc"; try{ int num = Integer.parseInt(str); }catch(NumberFormatException e){ System.out.println("数据类型是不是有一丢丢问题!!!"); }finally{
} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Test public void test2(){ String str = "123"; str = "abc"; try{ int num = Integer.parseInt(str); }catch(NumberFormatException e){ System.out.println("数据类型是不是有一丢丢问题!!!");
return; }finally{ System.out.println("我不管,我还会执行"); } }
|
throws + 异常类型
- throws + 异常类型 写在方法的声明出,指明此方法执行时,可能会抛出的异常类型。一旦执行时出现异常,仍会在异常代码出生成一个异常,此对象满足 throws 后边的异常类型时就会被抛出。异常代码后续的代码就不再执行。
体会:try - catch - finally 真正将一场处理掉了。
throws 只是将异常抛给方法的调用者,并没有真正将异常处理掉。
开发中如何选择使用try - catch - finally 还是 throws 处理异常?
- 如果父类中被重写的方法没有使用 throws 处理异常,则子类重写的方法也不能使用 throws ,意味着子类异常必须使用 try - catch - finally 方式处理。
- 执行的方法中先后又调用了另外几个方法,建议这几个方法使用 throws 处理异常,执行的方法使用 try - catch - finally 处理异常。
手动抛出异常
关于异常对象的产生:① 系统自动生成的异常对象
② 手动生成一个异常, 并抛出(throw)
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
| public class SrudentTest { public static void main(String[] args) { Student s = new Student(); s.regist(-100); System.out.println(s); } }
class Student{ private int id;
public void regist(int id){ if (id > 0){ this.id = id; }else{
throw new RuntimeException("您输入的非法!"); } }
@Override public String toString() { return "Student{" + "id=" + id + '}'; } }
|
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
| public class SrudentTest { public static void main(String[] args) { try{ Student s = new Student(); s.regist(-100); System.out.println(s); }catch(Exception e){ e.printStackTrace(); }
} }
class Student{ private int id;
public void regist(int id) throws Exception { if (id > 0){ this.id = id; }else{
throw new Exception("您输入的非法!"); } }
@Override public String toString() { return "Student{" + "id=" + id + '}'; } }
|
用户自定义异常类
- 如何自定义异常类:
- 继承于现有的异常结构,RuntimeException,Exception
- 提供serialVersionUID
- 提供重载构造器
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
|
public class MyException extends Exception{ static final long serialVersionUID = -3387516993124229948L;
public MyException(){
} public MyException(String msg){ super(msg); } }
public class SrudentTest { public static void main(String[] args) { try{ Student s = new Student(); s.regist(-100); System.out.println(s); }catch(Exception e){ e.printStackTrace(); }
} }
class Student{ private int id;
public void regist(int id) throws Exception { if (id > 0){ this.id = id; }else{
throw new MyException("不能输入负数"); } }
@Override public String toString() { return "Student{" + "id=" + id + '}'; } }
|