day17_异常
今日内容
零、 复习昨日
一、作业
二、异常
三、自定义异常
零、 复习昨日
见晨考,重点是String类的方法
StringBuffer和StringBuiler面试问
日期解析和格式化
int i = Integer.parseInt(“111”);
一、作业
略,见答案
二、异常
2.1 介绍
异常,就是程序出现的不正常的情况.
2.2 分类
在java程序设计中,关于异常有一大类,叫做Throwable
其下又有两个分类: Error,ExceptionError: 程序出现的
严重问题
,且只能抛出(throw),不能试图捕获(try catch)Exception: 是程序出现的问题,可以捕获可以抛出
2.3 编译期异常&运行期异常
-
运行期异常是RuntimeException及其子类
- 运行期异常就是指运行时会出现的异常
- 运行期异常可以不用主动处理
-
编译期异常是除了RuntimeException及其子类以外的所有异常
- 在编译期即运行前就已经提示有异常了
- 编译期必须处理(捕获or抛出)
public static void main(String[] args) throws ParseException {System.out.println(1/1 );// 这句话会出现运行时异常,ArithmeticExceptionSystem.out.println(1/0 );int[] arr = {1};// 这句话会出现运行时异常,ArrayIndexOutOfBoundsExceptionSystem.out.println(arr[2] );SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// parse()会出现编译期异常ParseException,需要处理Date date = sdf.parse("2000-01-01");}
2.4 异常的产生
异常是在方法时,代码内部使用
throw
来主动抛出
一个异常对象
public static void main(String[] args) throws ParseException{m1();// 此处也有异常,因为m1有抛出}// 产生异常public static void m1() {System.out.println(1/1 );throw new RuntimeException("没啥事,就是玩");// throw new ParseException("没啥事,就是玩2",1);}
一旦有异常产生,异常后的代码不再执行!!!
2.5 异常的处理
异常的处理的只有两种方案:
- 抛出(throws)
- 试图捕获(try catch)
2.5.1 抛出异常
异常的处理之抛出异常
什么叫抛出? 将错误信息给抛出到控制台给开发者看,将来也可以将异常信息给输出到本地磁盘,日志文件,邮件,数据库等等
抛出什么? 异常信息:异常类名,异常原因,异常位置
如何真正的抛出异常? 通过throw
抛出后如何处理? 一直向上抛,直到main,抛给jvm
具体怎么写? 在方法签名中,具体是在参数列表后,{}前使用throws关键词声明要抛出的异常类,如果有多个异常,可以使用逗号隔开
特别注意: 一旦有异常抛出,抛出异常后的代码不再执行!!!
throw 和 throws区别
throw throws 位置 方法内 方法签名上 跟的内容 1个异常对象 多个异常类名 功能 创建异常的 声明方法有异常
2.5.2 试图捕获
试图捕获异常,关键词 try…catch
与抛出异常最主要的区别: 捕获异常后,后续代码还能执行
语法:
try{// 正常的代码,或者说是感觉有可能出异常的代码 }catch(异常类名 对象名) {// 要抓的异常类名// 抓住后,可以做一些事情 }
执行流程:
- 执行try内代码
- 如果try内代码没有异常,跳过catch,去执行后续代码
- 如果try内代码有异常,与catch后要抓的异常匹配,如果一致则可以抓住,执行catch内代码,如果不一致,则抓不住,继续抛出
- 但是无论try-catch内是否有异常,try-catch后都能执行
public static void m1(){try{System.out.println(1/0 );}catch (NullPointerException ae){System.out.println("抓住啦空指针" );}catch (ArithmeticException ae) {System.out.println("抓住-算术" );}catch (ArrayIndexOutOfBoundsException ae){System.out.println("抓住-下标越界" );}}
try{System.out.println(1/1 );int[] arr = {1};System.out.println(arr[10] );}catch (Exception ae){// 可以写一个最大异常,只有可以捕获全部异常System.out.println("抓住啦-老大" );}
2.5.3 finally
finally不是用来处理异常的,只不过经常配合try,和catch语法一起使用,
语法: 放在try-catch后
执行流程: 无论有误有无报错,finally最终一定会执行
作用是: 释放资源
public static void m() {// try {// System.out.println(1/0);// } catch (Exception e) {// System.out.println("抓住异常");// } finally {// System.out.println("最终的-资源释放" );// }try {System.out.println(1/0 );}finally {System.out.println("最终的" );}}
2.6 异常的应用
- 如果是自己测试练习,那么异常就直接抛出
- 如果在开发时建议捕获异常,一方面是程序可以继续执行,一方面是捕获后可以再对异常进行处理
- 自己在设计方法时,方法异常尽量自己捕获
- 语法必须要求的: 重写时,子类方法异常范围要小于等于父类异常范围
@Overridepublic void m() throws Exception{SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 父类方法没有异常,子类只能捕获// try {// sdf.parse("2020-01-01");// } catch (ParseException e) {// e.printStackTrace( );// }}
2.7 异常的API
学异常的API是为了捕获到异常后,对异常的操作
发现所有异常的构造方法,和方法其实都是使用的Throwable类中的方法
- String getMessage() 获得异常的信息
- void printStackTrace() 将堆栈中异常信息打印到控制台
public static void main(String[] args) {try{// System.out.println(1/0 );int[] arr = {100};System.out.println(arr[1] );}catch (Exception e) {// 错误信息String message = e.getMessage( );// System.out.println(message );// 是将异常再重新打印出来e.printStackTrace();}
}
三、自定义异常
自定义异常,javase阶段用不上,一般是项目中设计使用
- 自定义类
- 继承异常体系中的类
- 继承Error,就不能捕获,只能抛出
- 继承Exception,必须处理
- 继承RuntimeException,默认可以不处理
- 设计无参,有参构造
- 使用super将异常信息向上传递给父类
- 在代码中使用throw 将异常对象抛出
public class AgeOutOfBoundsException extends RuntimeException{public AgeOutOfBoundsException(){}public AgeOutOfBoundsException(String message){super(message);}
}
public class Student {private int age;public int getAge() {return age;}public void setAge(int age) {if (age >= 0 && age <= 120) {this.age = age;} else {throw new AgeOutOfBoundsException("年龄"+age+"越界");}}
}
四、总结
对于现在而言,对于异常就是 顺其自然
但是要记住
- 异常的分类
- 编译期和运行时有什么区别
- 捕获和抛出语法
- 捕获后和抛出后什么影响
- 自定义异常,暂时用不上,在后期开发项目会用上