异常
Throwable
Error
- 定义:
不可修复的恶性错误,只能通过修改代码去规避错误,系统级别
例:定义一个数组int[] arr = new int[1024 * 1024 *1024];
此时会报内存溢出异常 java.lang.OutOfMemoryError,此异常与系统有关,若想要规避此异常,只能通 过修改源码的方式
Exception
- 定义:
可修复的良性异常,程序员可以通过代码修正(try catch处理,不需要修改源码)的方式纠正,使程序正常运行
编译时异常:checked时异常
- 继承exception类,再编译时抛出异常,需要try catch 处理,或throw处理,一直将异常抛出直至到main方法,交由jvm虚拟机处理
运行时异常:runtime异常
- RunTimeException类,Exception的子类,编译时不抛出异常,程序运行时抛出异常
异常的关键字
throw
- 在方法体中抛出异常
若在方法体抛出的异常为编译期异常,需要对throw的异常try{}catch(){}处理 , 或在方法声明throws处理
throws
- 在方法声明出抛出一个异常
可抛出多个异常,异常之间用, 逗号隔开,方法体throw的异常有子父类关系,抛出父类异常即可
try{} catch{} finally{}
-
try{}
放置可能发生异常的语句 -
catch(用来接收异常对象){}
- catch(Eeception e){
//对发生的异常进行处理,一般做 记录日志/打印异常信息/连续抛出异常动作
} - catch(){}的处理原理:
首先try 中可能发生异常的语句抛出异常对象,使用Exception 接收try 中抛出的异常对象,并在{},做出相应的处理
- catch(Eeception e){
-
finally{}
一定会执行的语句,一般用于关闭资源操作,若在finally{}, 放置return,则方法返回的永远是finally的返回值
异常捕获的3种方式
-
异常捕获的3种方式
1.多个异常,分别处理
try{
}catch(){
}
try{
}catch(){
}
try{
}catch(){
}
一个异常,对应一个try catch
2.多个异常,一次捕获,多个处理
try{
}catch(){
}catch(){
}
catch(){
}
一个try捕获多个异常,多应多个catch
注意:当try 中可能抛出的异常同时含有子父类的异常,注意catch 子符类异常的位置关系
catch时子类异常应该放在父类异常上面
原因:当try中父类发生异常不能使用子类异常对象去接收
当try中子类发生异常是可以使用父类对象去接收的
多态,只能将子类对象向上转型的父类对象 赋给子类对象)3.多个异常,一次捕获,一次处理
try{
}catch(){
}
try中可能抛出的异常有一个公共的父类异常
Jvm虚拟机检测异常的动作
- Jvm虚拟机在普通方法的方法体内检测到异常
- 创建异常对象 异常对象内容(异常信息:即异常包名,类名, 异常原因,异常位置)
- 若抛出异常的方法中有try catch 语句,执行 try catch语句,若有声明异常throws,则将创建的的异常对象抛给调用该方法的方法,进行try catch 处理,若没有try catch 处理则一直将该异常对象往上抛,直至抛到main方法,交由Jvm虚拟机处理
- Jvm虚拟机在main方法中接收异常
- 将异常对象以红色字体打印到控制台
- 停止在执行的程序
子父类异常的继承关系
- 子类继承父类时只能抛出和父类相同的异常或异常的子类或不抛出异常
即:当子类去继承一个类,该类有抛出异常,子类只能做如下的几个动作
- 抛出和父类相同的异常
- 抛出父类异常的子类
- 不抛出异常
- 不能抛出其他非父类的异常
即要么不抛,抛也只能抛父类异常或父类异常的子类
异常的使用
程序开发时,当用户给方法传递参数时一般都要定义一个参数异常,判断用户传递的参数是否符合规范,是否为空
使用Object的静态方法 RequireNonNull(),方法判断参数对象是否为空
Object.RequireNonNull(对象) //若对象为空,抛出一个NullPointException()
底层:判断对象是否为空,若为空,抛出一个NIullPointException,不为空,返回一个对象
重载方法:RequireNonNull(obj,异常原因) //若对象为空,抛出一个NullPointException(异常原因)
Throwable的3个方法
String getMesage() //打印 异常原因
String toString() //打印异常 包名.类名+异常原因
catch中捕获的异常对象 Exception e 打印 e时调用的就是 toString()方法
String prinitStackTrance() //打印异常 包名.类名+异常原因+异常位置
控制台打印调用的就是printStackTrance()方法
自定义异常类
- 步骤
-
实现Exception
以为exception具有可抛性,可抛性是Throwable这个体系特有的特点,只有这个体系的类才能被throw和throws -
定义异常信息
两个构造器:
一个空的构造器
XxxException(){
super();
}
一个有参数的构造器,带异常信息
XxxException(message){
//在构造器中使用显示的supper(异常信息),将异常信息传递进去
super(message)
} -
使用
在可能出现异常的语句中通过throw抛出可能的异常
当抛出的异常为编译时异常时:
需要对方法可能出现异常的语句进行try 和 catch处理,或在方法声明处throws异常
当抛出的异常为运行时异常时:
不用做特殊处理,程序调用时,Jvm虚拟机会自动识别- 自定义编译时异常
/**-
自定义异常类
*/
public class ExceptionTest01 extends Exception {
private int value;
public ExceptionTest01() {
super();
}
public ExceptionTest01(String msg, int value) {
//自定义异常信息,将msg传给父类的构造方法
super(msg);
this.value = value;
}
public int getValue() {
return value;
}
}
public class ExceptionTest02 {
public static void main(String[] args) throws ExceptionTest01 {
int i = div(1, -1);}
/**
-
自定义编译时异常,在语句throw,必须在方法声明throws
-
@param a
-
@param b
-
@return
-
@throws ExceptionTest01
*/
public static int div(int a, int b) throws ExceptionTest01 {
if (b < 0) {
throw new ExceptionTest01("出现了除数是负数的情况", b); //手动通过throw关键字抛出一个自定义异常对象。
}
return a / b;
}
自定义运行时异常
public class NoScoreException extends RuntimeException {
// 空参构造
public NoScoreException() {
super();
}
// 有参构造
public NoScoreException(String message) {
super(message);
}
}
public class Student {
private String name;
private int score;
// 空参构造
public Student() {
super();
}
// c)提供有参构造;
// i.使用setXxx方法给名称和score赋值
public Student(String name, int score) {
setName(name);
setScore(score);
}
// d)提供setter和getter方法public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public int getScore() {
return score;
}
// i.在setScore(int score)方法中
public void setScore(int score) {
// 1.首先判断,如果score为负数,就抛出NoScoreException,异常信息为:分数不能为负数:xxx.
if (score < 0) {
throw new NoScoreException(":分数不能为负数:" + score);
}
// 2.然后在给成员score赋值.
this.score = score;
}
}
-
-
- 自定义编译时异常
-