1 异常体系
1.1 概念
程序在运行过程中 出现非正常情况
异常类:用于程序出非正常情况的类
异常体系:继承关系的异常类
1.2 异常体系特点
1:异常体系的顶层父类:Throwable:::类是 Java 语言中所有错误或异常的超类
2:Throwable的子类按严重情况分成:Error错误+Exception异常
3:异常体系的类:基本没有特有方法 方法都继承于Throwable
异常体系类的不同之处:1 类名+2 异常原因
4:Error和Exception的子类都是以父类的名字结尾
1.3 Error和Exception的区别
概念:Error错误 Exception异常
相同之处:都是Throwable的子类 都是异常体系的类
不同之处:1 Exception是异常 可以通过代码逻辑进行处理
Error是错误 不能通过代码逻辑进行处理的严重情况 只能修改代码
2 Exception一般是可以预料的意外
Error是不能预料的严重错误 一般是jvm/内存出现错误
1.4 Throwable的常用方法
public static void main(String[] args) {
/*构造方法:
* 1 无参数的:Throwable() 没有指定异常原因:为null
* 2 有参数的:Throwable(String message) 指定异常原因
* 普通方法:
* 1 获取异常原因:String getMessage()
* 2 打印错误输出流信息:void printStackTrace()
* java.lang.Throwable: 异常原因!! //遗产类型:异常原因
* at day11_basic_class.Demo01Throwable.main(Demo01Throwable.java:14) //异常的位置
* 3 获取对象的字符串表示形式:String toString()
* java.lang.Throwable: 异常原因!! //遗产类型:异常原因
* */
Throwable t1=new Throwable();
Throwable t2=new Throwable("异常原因!!");
System.out.println("getMessage="+t1.getMessage());
System.out.println("getMessage="+t2.getMessage());
//System.out.println(1/0);/// by zero
t1.printStackTrace();
System.out.println("---------");
t2.printStackTrace();
//ehhe2();
System.out.println(t1);
System.out.println(t2);
}
public static void ehhe1() {
System.out.println(1/0);
}
public static void ehhe2() {
ehhe1();
}
1.5 异常体系的学习重点
1 理解java描述异常的思想:把异常情况封装为对象:提取数据作变量 提取功能做方法
2 异常分类:
3 异常体系的特点
4 处理异常的两种机制
5 异常处理的所有关键字
6 自定义异常
1.6 目前已有的Exception和Error
- 已有的异常
int[] arr=new int[2];
//System.out.println(arr[2]);//ArrayIndexOutOfBoundsException: 2
//System.out.println("123".charAt(3));//StringIndexOutOfBoundsException: String index out of range: 3
Object obj="123";
//System.out.println((Date)obj);//ClassCastException: java.lang.String cannot be cast to java.util.Date
String s=null;
//System.out.println(s.charAt(1));//NullPointerException
//int n=new Scanner(System.in).nextInt();//InputMismatchException
//int n=Integer.parseInt("abc");//NumberFormatException
//Date date=new SimpleDateFormat("yyyy-MM-dd").parse("1234/11/12");//ParseException
System.out.println("1234".getBytes("jkl"));//UnsupportedEncodingException
- 常见的错误
package day11_basic_class;
public class Demo02 {
public static void main(String[] args)throws Exception {
//A a1=new A();
//a a2=new a();
//类未定义错误:NoClassDefFoundError: day11_basic_class/A (wrong name: day11_basic_class/a)
//{
//语法错误://Error: Unresolved compilation problem:
//long[][] arr2=new long[65*10][1024*1024];
//内存移除错误://OutOfMemoryError: Java heap space
//hehe();
//栈移除错误://StackOverflowError
}
public static void hehe() {
hehe();
}
}
class A{}
class a{}
2 处理异常的方式
现实生活中:比如敲代码 出现异常 比如说电脑冒烟了
处理问题:两个选择:1 自己修 修完后 继续敲代码 --- 捕获机制
2 把这个情况上报给上级(调用者) 让调用者处理 剩下的工作不做了 --- 抛出机制
捕获机制:在方法体中通过try-catch代码块对可能生产的异常对象进行处理
抛出机制:在方法声明上通过throws 把可能生产的异常对象抛给方法的调用者
2.1 抛出机制
抛出机制:在方法声明上通过throws 把可能生产的异常对象抛给方法的调用者
package day11_basic_class;
...
public class Demo03Throws {
public static void main(String[] args) throws ParseException, UnsupportedEncodingException, FileNotFoundException{
test01();
System.out.println(111);
}
//抛出机制的格式:在方法声明上通过throws 异常类型
//抛出机制的作用: 1 声明当前方法可能产生那些异常
// 2 如果产生了这些异常 当前方法不处理 而是把异常对象抛给方法的调用者
//抛出机制类似于:商品上的警告标签
//抛出机制注意事项: 1 如果一直使用抛出机制 异常最终抛给jvm:
// jvm处理异常的统一方式:调用异常的printStackTrace方法打印异常的详细详细 然后停止虚拟机
// 2 通过抛出机制来处理异常 如果产生异常 当前方法直接终止 不再执行当前方法中的其他代码
// 3 抛出机制是一种消极处理异常的方式 尽量避免
// 4 子类方法抛出的异常可以和父类方法相同 或者被父类方法抛出的异常兼容
public static void test01() throws ParseException, UnsupportedEncodingException, FileNotFoundException {
Date date=new SimpleDateFormat("yyyy-MM-dd").parse("1234-11-12");//ParseException
System.out.println("1234".getBytes("gbk1"));//UnsupportedEncodingException
System.out.println(111);
FileInputStream fin=new FileInputStream("C:\\Users\\Administrator\\Desktop\\作业111.txt");//FileNotFoundException
Demo03Zi z1=new Demo03Zi();
}
}
class Demo03Fu{
void test01() throws Exception{}
//重载对异常没有要求:
//void test01() throws ParseException, UnsupportedEncodingException, FileNotFoundException {}
}
class Demo03Zi extends Demo03Fu{
//子类重写父类的方法:子类方法抛出的异常可以和父类方法相同 或者被父类方法抛出的异常兼容
void test01() throws ParseException, UnsupportedEncodingException, FileNotFoundException,IOException{}
//重载对异常没有要求:
//void test01() throws ParseException, UnsupportedEncodingException, FileNotFoundException {}
//总结重写的要求:范围修饰符可以扩大 抛出的以上可以少/小 其他方法声明必须和父类完全相同
}
2.2 捕获机制
捕获机制:在方法体中通过try-catch代码块 对可能产生的异常对象进行处理
public static void main(String[] args){
test01();
System.out.println("main结束");
}
/*
* 捕获机制:
* 格式: try {
* 可能产生异常的代码块
* }catch(定义引用1 用于接收捕获到的异常对象1) {
* 处理异常对象的代码
* }catch(定义引用2 用于接收捕获到的异常对象2) {
* 处理异常对象的代码
* }finally{
* 不管然后处理异常 不管是否出现异常 一定要执行的代码
* }
* 注意1:如果try代码块出现异常 就执行对应类型的catch代码块:try代码块终止执行
* 注意2:捕获父类异常的catch代码块必须放在捕获子类异常的catch代码块后面
* 注意3:不管然后处理异常 不管是否出现异常 一定要执行finally代码块:除非:System.exit(0);
* 一般情况下:finally代码块 中是释放连接 关闭流的代码
* */
public static void test01(){
System.out.println("test01方法开始");
try {
System.out.println("try开始。。。");
Date date=new SimpleDateFormat("yyyy-MM-dd").parse("1234-11-12");//ParseException
System.out.println("1234".getBytes("gbk"));//UnsupportedEncodingException
System.out.println(111);
FileInputStream fin=new FileInputStream("C:\\Users\\Administrator\\Desktop\\作业.txt");//FileNotFoundException
System.out.println("try结束。。。");
//System.out.println(new long[100*65][1024][1024*1000]);
System.exit(0);
}catch(ParseException e) {
//捕获到ParseException异常时 要执行的代码
System.out.println("ParseException:::"+e.getMessage());
}catch(UnsupportedEncodingException e) {
//捕获到UnsupportedEncodingException异常时 要执行的代码
System.out.println("UnsupportedEncodingException:::"+e.getMessage());
}catch(FileNotFoundException e) {
//捕获到FileNotFoundException异常时 要执行的代码
System.out.println("FileNotFoundException:::"+e.getMessage());
}catch(Exception e) {
//捕获到Exception异常时 要执行的代码
System.out.println("Exception:::"+e.getMessage());
}finally {
System.out.println("finally代码块");
}
System.out.println("test01方法结束");
}
3 Exception的分类
/*
*Exception的分类:根据是否继承RuntimeException分类
*运行时异常:直接或者间接继承RuntimeException 未检查异常
*编译时异常:没有继承RuntimeException 已检查异常
*
*不同之处:
* 1 是否继承RuntimeException
* 运行时异常:直接或者间接继承RuntimeException
* 编译时异常:没有继承RuntimeException
* 2 编译器是否检查:
* 编译器不对运行时异常进行检查
* 编译器如果检查到编译时异常 要求必须处理(捕获/抛出) 否则编译器报错
* 3 出现频率
* 编译时异常只有指定方法被调用时 才可能产生 出现的频率低
* 运行时异常一般出现的频率比较高
* */
public static void test02(){
// System.out.println("try开始。。。");
// Date date=new SimpleDateFormat("yyyy-MM-dd").parse("1234-11-12");//ParseException
// System.out.println("1234".getBytes("gbk"));//UnsupportedEncodingException
// System.out.println(111);
// FileInputStream fin=new FileInputStream("C:\\Users\\Administrator\\Desktop\\作业.txt");//FileNotFoundException
// System.out.println("try结束。。。");
System.out.println(1/0);
System.out.println((String)new Object());
System.out.println("".charAt(0));
String s=null;
System.out.println(s.charAt(0));
System.out.println(Integer.parseInt("abc"));
}
4 自定义异常
4.1 明确
为什么要自定义异常:现有的异常(jre中已定义的异常)没法满足项目的需求
异常类的不同之处:1 异常类名 2 异常原因(通过构造方法的参数列表来指定)
注意:只有直接或者间接继承Throwable 才能称为异常类
4.2 自定义异常
package day11_basic_class;
...
public class Demo06Exception {
/*
* throws 与throw的区别
* 都是处理异常的关键字
* 不同之处1:位置不同
* throws用在方法声明上 用于表示当前方法可能产生那些异常情况 如果产生异常 就抛给方法的调用者
* throw用在方法体中 用于表示当前方法出现异常情况
* 不同之处2:后面跟的内容不同
* throws后面根一个或者多个异常类型
* throw后面根一个异常对象
* 不同之处3:作用不同
* throws表示当前方法可能产生那些异常情况 如果产生异常 就抛给方法的调用者
* throw表示当前方法出现异常情况
* */
public static void main(String[] args)throws MyException061{
MyException061 m1=new MyException061("输错了!");//创建了一个异常对象 不表示程序出现异常情况
//3 通过throw 异常对象 ;出现指定的异常情况
//throw m1;
//4 对产生的异常对象进行处理
//System.out.println(m1.getMessage());
test01(-1);
System.out.println(111);
}
//4 对产生的异常对象进行处理
public static void test01(int age) throws MyException061{
if(age<0) {
//3在指定情况下:: 通过throw 异常对象 ;出现指定的异常情况
throw new MyException061("年龄太小了!");
}
System.out.println("age="+age);
}
/*
自定义异常:
1 定义类 继承Throwable或者其子类
2 通过构造方法的参数列表来指定异常原因
3 在指定情况下:: 通过throw 自定义异常对象 ;出现指定的异常情况
4 对可能产生的异常对象进行处理
* */
}
//1 定义类 继承Throwable或者其子类
class MyException061 extends Exception{
//2 通过构造方法的参数列表来指定异常原因
MyException061(String message){
super(message);
}
}