java 异常举例_Java异常相关知识总结

异常:

概述:java程序运行过程中出现的错误

常见的异常:

StackOverflowError

ArrayIndexOutOfBoundsException

NullPointerException

ClassCastException

ParseException

异常的分类:

Trowable:

1.--Error: a.相当于天灾人祸,虚拟机出现了问题

2.--Exception:

1).RuntimeException:运行过程中出现的异常 可以处理可以不处理,一般出现这种问题都是代码逻辑有问题,推荐修改代码

2).编译期异常:出发之前因该检查的异常,必须处理,负责编译不通过

1,编译时异常: 除了RuntimeException及其子类,Exception中所有的子类都是,这种异常必须要处理,要不编译通不过。

2,运行时异常 :RuntimeException及其子类都是,这种异常不用处理,编译会通过,不过这样的程序会有安全隐患,遇到这种异常是需要改代码的。

3,严重错误问题 :用Error进行描述,这个问题发生后,一般不编写针对代码进行处理,而是要对程序进行修正.通常都是由虚拟机抛出的问题。

542975b00e589fbf9e09ec91580bcdc4.png

举例说明:

异常分三类:

骑车去旅行:

Error:走到半路上,发生山路塌陷,或者出现了泥石流,这个问题很严重,不是班长能够立马解决的。

Exception:出门前,班长要看看车轮子以及车链子等是否还在

RuntimeException:在骑车的过程中,有好路不走,偏偏要走石子路

异常举例:

1 //异常测试:2 //a.除数为03 //b.数组越界

4 public classHomeWork_02 {5 public static voidmain(String[] args) {6 System.out.println("start");7 f1();8 //f2();

9 System.out.println("end");10 }11 //数组越界异常

12 public static voidf2(){13 int[]arr={1,2,3};14 System.out.println(arr[0]);15 System.out.println(arr[1]);16 System.out.println(arr[2]);17 //System.out.println(arr[3]);//ArrayIndexOutOfBoundsException: 3

18 }19 //除数为0异常

20 public static voidf1(){21 int a=23;22 int b=0;23 System.out.println(a/b);//ArithmeticException: / by zero

24 }25 }

jvm对异常的默认处理:

a. 哪个线程出现的问题

b. 异常的类型以及详细信息

c. 调用栈信息

d. 终止程序

如下图为异常举例代码中数组溢出是jvm所报的错误:

f64277c62043157b29ae25c129395cda.png

因为jvm处理异常的时候直接停止了程序,所以我们要学会自己处理异常:

如何自己处理异常:

a. try...catch...finally

b. throws

1. try...catch...finally语句

try {

要检查的代码

} catch (异常类型 对象名) {

对异常的处理

} finally {

释放资源

}

a. 一种异常的情况

1 public classExceptionDemo_03 {2 public static voidmain(String[] args) {3 System.out.println("Start");4 int a =10;5 int b=0;6 try{7 System.out.println(a/b);8 System.out.println("one");9 System.out.println("two");10 System.out.println("three");11 }catch(ArithmeticException e){12 System.out.println("除数为0");13 System.out.println(e);14 }15 System.out.println("end");16 }17 }

//问题:为什么e局部变量会有值?

//如果try里面出现了异常, JVM会把异常信息封装成对应类型的异常对象。

//然后和catch语句依次匹配,找到对应的异常类型,然后把它赋值给引用变量e

输出结果:

f80d0e02c15430d6d341b0afb218a66a.png

注意事项:

a. try里面的代码越少越好,最好只放可能出现异常的代码

b. try里面出现了异常,就不会执行try里面里面后序的代码

c. ArithmeticException e 是局部变量, 作用范围是对应的catch语句。

d. catch 捕获了异常,执行对应的处理,异常就不再存在了。

b.多种异常的情况:

a. 一个一个处理

b. 一次性处理

c. JDK7 新特性

把多个处理方式相同的catch语句,合成一个catch语句。

catch(类型1 | 类型2 | 类型3... e)

注意事项:

一个try语句中, 最多只会抛出一个异常,最多也只会执行一个catch语句

如果异常没有兼容惯性,谁先谁后没关系,如果有兼容关系,那么父类应该方法在子类之后。

JDK7新特性, 一个catch 语句不能出现子父类关系

测试代码:

1 /*多种异常的情况:2 a. 一个一个处理3 b. 一次性处理4 处理方式相同的catch语句,合成一个catch语句。5 catch(类型1 | 类型2 | 类型3... e)*/

6 public classExceptiomDemo_04 {7 public static voidmain(String[] args) {8 System.out.println("start");9 /*try {10 f1();11 f2();12 // f2()在后面的时候,执行到f1()的时候就不再往下执行了,没有输出arr[0],arr[1],arr[2]13 } catch (ArithmeticException e) {14 // System.out.println("除数为0");15 System.out.println("发生了异常");16 } catch (ArrayIndexOutOfBoundsException e) {17 // System.out.println("数组索引越界");18 System.out.println("发生了异常");19 } catch (Exception e) {20 System.out.println("其他异常");21 }*/

22 try{23 f2();24 f1();25 } catch (ArithmeticException |ArrayIndexOutOfBoundsException e) {26 System.out.println("除数为0或者数组索引越界");27 }28

29

30 }31 public static voidf2(){32 int []arr={1,2,3};33 System.out.println(arr[0]);34 System.out.println(arr[1]);35 System.out.println(arr[2]);36 System.out.println(arr[3]); //ArrayIndexOutOfBoundsException: 3

37 }38 public static voidf1(){39 int a =10;40 int b=0;41 System.out.println(a/b);//ArithmeticException: / by zero

42

43 }44 }45

编译期异常和运行时异常:

Exception:

|-- 运行时异常: RuntimeException和其子类。

可以显示处理,也可以不处理,一般出现运行时异常,都是代码逻辑有问题,推荐修改代码逻辑。

|-- 编译期异常:其他类。无论运行时是否发生异常,都必须显示处理,否则无法通过编译。

测试代码:

1 importjava.text.ParseException;2 importjava.text.SimpleDateFormat;3 importjava.util.Date;4 importjava.util.SimpleTimeZone;5

6 //编译期异常和运行时异常:

7 public classExecptionDemo_05 {8 //一般不要在主方法中抛出异常,这里为方便在主方法中抛出异常

9 public static void main(String[] args) throwsParseException {10 //运行时异常:

11 int a=10;12 int b=0;13 try{14 System.out.println(a/b);15 }catch(ArithmeticException e){16 System.out.println("除0异常");17 }18 //编译期异常,不解决不能通过编译

19 Date time=newDate();20 SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");21 String date=sf.format(time);22 System.out.println(date);23 Date date1=sf.parse(date);//ParseException

24 }25 }

Throwable

Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。

类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

构造方法摘要:

Throwable()

构造一个将 null 作为其详细消息的新 throwable。Throwable(String message)构造带指定详细消息的新 throwable。

成员方法:返回此 throwable 的详细消息字符串。默认实现:getClass().getName()+“:”+getMessage();

返回此 throwable 的简短描述。

void printStackTrace() //推荐使用它,而且输出内容会用红色标识

将此 throwable 及其追踪输出至标准错误流。

注意:通常e.getMessage()并不能获取全部的错误信息,需要用到e.printStackTrace()查看完整错误信息,但是这个方法是void 只能在控制台输出。

测试代码:

1 importjava.text.ParseException;2 importjava.text.SimpleDateFormat;3 importjava.util.Date;4

5 //Throwable():、

6 public classExceptionDemo_06 {7 public static voidmain(String[] args) {8 String s = "2001/01/01 00:00:00";9 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");10 Date date = null;11 try{12 date=sdf.parse(s);13 }catch(ParseException e){14 System.out.println("解析异常");15 System.out.println(e.getMessage());16 System.out.println(e.toString());17 e.printStackTrace();18 }19 }20 }

ce07fe5fcc6ad3a079e983fa1fd58af0.png

thorws

定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。

举例:

村里出现了问题,如果能自己解决就自己解决,解决不掉就交给乡里,乡里解决不掉就抛给县里解决, 县里解决不掉,抛给市里,如果市里解决不掉,抛给省里,如果省里解决不掉,抛给中央。中央就直接干掉。

throws: 把问题抛给调用者

a.编译期异常

b.运行期异常

注意事项:

不要在main()方法抛出异常,如果抛出异常就会执行JVM的默认处理。

测试代码:

1 importjava.text.ParseException;2 importjava.text.SimpleDateFormat;3 importjava.util.Date;4

5 public classExceptionDemo_07 {6 public static voidmain(String[] args) {7 String s = "2019/7-9 11:31:00";8 String pattern = "yyyy-MM-dd HH:mm:ss";9 Date date = null;10 try{11 date =string2Date(s, pattern);12 } catch(ParseException e) {13 e.printStackTrace();14 }15 System.out.println(date);16 int a = 10;17 int b = 0;18 int c = 0;19 try{20 c =f1(a, b);21 } catch(Exception e) {22 e.printStackTrace();23 }24 System.out.println("c = " +c);25 System.out.println("end");26 }27 //throw:告诉调用者,注意:调用这个方法可能会有某某异常

28 public static Date string2Date(String s, String pattern) throwsParseException {29 SimpleDateFormat sdf = newSimpleDateFormat(pattern);30 returnsdf.parse(s);31 }32 public static int f1(int a, int b) throwsException{33 //return a / b;

34 if (b != 0) {35 return a /b;36 }37 throw new Exception("除0异常");38 }39 }

throw

在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。

测试代码:

throws和throw的区别

throws

用在方法声明后面,跟的是异常类名

可以跟多个异常类名,用逗号隔开

表示抛出异常,由该方法的调用者来处理

throws表示出现异常的一种可能性,并不一定会发生这些异常

throw

用在方法体内,跟的是异常对象名

只能抛出一个异常对象名

表示抛出异常,由方法体内的语句处理

throw则是抛出了异常,执行throw则一定会出现异常, throw抛出了一个实实在在的异常

1 importjava.util.Scanner;2

3 //举例:4 //录入学生成绩 [0~100]

5 public classExecptionDemo_08 {6 public static voidmain(String[] args) {7 System.out.println("请输入学生成绩");8 Scanner sr =newScanner(System.in);9 int score=sr.nextInt();10 //数据验证

11 try{12 checkScore(score);13 }catch(Exception e){14 e.printStackTrace();15

16 }17 }18 public static void checkScore(int score) throwsException {19 if(score<0||score>100){20 throw new Exception("score="+score);21 }22 //throw抛出了异常后,后面的语句就不再执行

23 System.out.println("one");24 System.out.println("two");25 System.out.println("three");26 }27 }

6eab529e27d5a6e7d00a4e28f2e40ce5.png

我们到底该怎么处理异常:

原则:如果该方法知道如何处理,那用try...catch, 如果不知道怎么处理,就抛给它的调用者去处理。

区别:

如果try...catch,后续代码会执行。

如果throws,后续代码不会被执行。

try语句的变形

try...catch

try...finally

try...catch...finally

try...catch...catch...

try...catch...catch...finally

finally语句:

特点:

被finally控制的语句体无论出现异常还是没有出现异常,都会执行。

特殊情况:在执行到finally之前jvm退出了. System.exit();

作用:

释放系统资源

final和finally和finalize区别:

final: 最终的

类:不能被继承

方法:不能被重写

变量:常量

finally:

try语句的子句。

finally里面的语句, 无论出现异常还是不出现异常,都会被执行。

用来释放资源。

finalize:

Object中的方法。

对象被回收前,该方法会被自动执行。用来释放资源。

手动调用该方法,对象不会被回收。

1 importjava.text.ParseException;2 importjava.text.SimpleDateFormat;3 importjava.util.Date;4

5 public classExceptionDemo_09 {6 public static voidmain(String[] args) {7 String s = "2019/7/9 14:40:00";8 String pattern = "yyyy-MM-dd HH:mm:ss";9 SimpleDateFormat sdf = newSimpleDateFormat(pattern);10 try{11 Date date =sdf.parse(s);12 } catch(ParseException e) {13 e.printStackTrace();14 //finally只有在执行到finally之前虚拟机就退出的时候才会不执行15 //System.exit(0);

16 } finally{17 System.out.println("finally子句");18 }19 System.out.println("end");20 }21 }

fe6a0c2ed8371c4df6de527e88f29d8d.png

如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问结果是怎样的?

finally语句会被执行

第一次执行return语句,就已经生成了返回路径, 并把返回值保存起来了。

后面在finally语句中修改变量,不会影响返回值。

如果finally中也有return语句。

最终执行的是finally中语句。

1 public classExceptionDemo10 {2 public static voidmain(String[] args) {3 System.out.println(method()); //40

4 }5

6 public static intmethod() {7 String s = "2019/7/9 14:40:00";8 String pattern = "yyyy-MM-dd HH:mm:ss";9 SimpleDateFormat sdf = newSimpleDateFormat(pattern);10 int a = 10;11 try{12 a = 20;13 Date date =sdf.parse(s);14 } catch(ParseException e) {15 a = 30;16 returna;17 } finally{18 System.out.println("finally");19 a = 40;20 return a; //生成了另外一条返回路径

21 }22

23 }24 }

自定义异常:

类名就代表异常的种类(信息)

编译期异常:继承Exception

运行时异常:继承RuntimeException

异常类:

1 public class ScoreException extendsRuntimeException {2 publicScoreException(){3 super();4 }5 publicScoreException(String message){6 super(message);7 }8 }

测试类:

1 public classEceptionDemo_11 {2 public static voidmain(String[] args) {3 System.out.println("请录入学生成绩;");4 Scanner scanner = newScanner(System.in);5 int score =scanner.nextInt();6 //数据验证

7 /*try {8 checkScore(score);9 // 存入数据库10 } catch (ScoreException e) {11 e.printStackTrace();12 }*/

13 checkScore(score);14 }15 private static void checkScore(int score) throwsScoreException{16 if (score < 0 || score > 100) {17 //throw new RuntimeException("score=" + score);

18 throw new ScoreException("score=" +score);19 }20 }21 }

异常注意的事项:(编译期异常)

子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。

如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

儿子不能比父亲更坏。一代只能比一代强。

编译的时候,不检查运行时异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值