今日内容
零、 复习昨日
一、作业
二、异常
三、自定义异常
零、 复习昨日
见晨考,重点是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 ); // 这句话会出现运行时异常,ArithmeticException System.out.println(1/0 ); int[] arr = {1}; // 这句话会出现运行时异常,ArrayIndexOutOfBoundsException System.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 异常的应用
- 如果是自己测试练习,那么异常就直接抛出
- 如果在开发时建议捕获异常,一方面是程序可以继续执行,一方面是捕获后可以再对异常进行处理
- 自己在设计方法时,方法异常尽量自己捕获
- 语法必须要求的: 重写时,子类方法异常范围要小于等于父类异常范围
@Override
public 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+"越界");
}
}
}
四、总结
对于现在而言,对于异常就是 顺其自然
但是要记住
- 异常的分类
- 编译期和运行时有什么区别
- 捕获和抛出语法
- 捕获后和抛出后什么影响
- 自定义异常,暂时用不上,在后期开发项目会用上