Skip to content

Java异常处理机制

1714字约6分钟

java

2024-10-24

1.异常的定义

当程序违反Java编程的语义约束时 ,Java虚拟机将这个错误作为一个异常;

2.异常的分类

按处理方式

1.不能处理的(Error)例:虚拟机错误、IO错误、动态链接库错误

2.必须进行处理的(Check Exception)受控异常

例:ClassNotFoundException、DataFormatException、IOException->FileNotFoundException、

3.可处理可不处理(RuntimeException)运行时异常(JVM默认处理了这些)

例:NullPointException、ArrayIndexOutOfException、StringIndexOutOfException

image-20210923090815292

Throwable是Error和Exception的父类

3.异常处理的方式

1.利用try.....catch(Exception e)........finally.......捕获异常

try表可能产生异常的代码块(异常捕获范围,有大括号且不可省略)

catch(异常参数)异常处理代码,可以有多个异常参数(JDK7以后)

可以有多个catch代码块

finally:无论异常发生与否必须执行的代码,只能有一个代码块,不能写在catch之前

catch/finally有一个就可以且catch可以有多个

try {
	// try代码块存放可能会发生异常的代码
	System.out.println(12/x);
} catch (Exception e) {
    // 异常处理代码,运行时异常可处理也可不处理,处理方式就是提示
	// 打印栈跟踪信息
	e.printStackTrace();
}finally{
	// finally无论有无异常都会执行
	System.out.println("异常");
}

2.利用throws关键字将异常处理的自然==责任交给上级(本方法的调用者)

4.Throwable的两个方法

printStatckTrace()方法打印栈跟踪信息

getMessage()返回异常信息

5.throws与throw关键字的区别

1.使用位置不同

throw在方法体中使用,用来抛出一个异常

throws在方法的定义中(签名)

2.功能不一样

throw用来抛出异常

throws表示把异常处理的责任给它的调用者

3.效果不同

throw一定有异常抛出

throws不一定会产生异常

throw:

1.表示方法内抛出某种异常对象 2.如果异常对象是非 RuntimeException 则需要在方法申明时加上该异常的抛出 即需要加上 throws 语句 或者 在方法体内 3.try catch 处理该异常,否则编译报错 4.执行到 throw 语句则后面的语句块不再执行

throws:

1.方法的定义上使用 throws 表示这个方法可能抛出某种异常

2.需要由方法的调用者进行异常处理

6.catch的范围顺序

先捕获小范围的异常,再捕获范围大的异常

若后面捕获的异常是前面的子异常,会报编译错误

先捕获子异常再捕获父异常,若相反会报编译错误

7.重写中异常处理的三种方式

1.throw原异常

2.不再处理

3.throw子异常

8.应用

能try就try,指用于处理业务信息足够且不需要让上一级调用者了解的异常

throws可以让代码更加简洁,提高可读性。用于业务信息不足不能处理从而交给它的调用者处理的情况

先try再throw或再catch代码块中throw异常

AOP(面向切面能编程)的处理方式

自定义异常

自定义异常,是在某一些特殊情况下,JDK自带的异常无法准确描述异常情况时,采用自己定义异常类的方式封装异常信息。

1.定义自定义异常类,继承至某个Exception类,重写其中构造方法。

2.在代码中检测到某个条件成立,需要抛出异常的位置,使用throw 语句抛出自定义异常类的实例

3.在代码所在的方法后面,添加throws 字句,表示方法有一个自定义异常类型的异常信息需要处理

4.在方法的调用者处理异常信息。

    class DivideZeroException extends Exception{
    	public DivideZeroException() {
    		super();
    	}
    	public DivideZeroException(String message){
    		super(message);
    	}
    }
    public class Test {
    	public static int divide(int a, int b) throws DivideZeroException {
    		if(b==0){
    			throw new DivideZeroException("除以0异常");  
    		}
    		return a / b;
    	}
     
    	public static void main(String[] args)  {
    		try{
    			int result = divide(10, 0);
    			System.out.println(result);
    		}catch(DivideZeroException e){
    			e.printStackTrace();
    		}
    		System.out.println("程序继续执行");
    	}
    }

不好的处理方式

1.chatch all(catch(Exception e))

2.嵌套catch

3.静默处理(没有任何提示)

异常处理的步骤:

提示、记录错误信息、报告上级

9.JDK7后新的处理方式

try-with-resources语句是一种声明了一种或多种资源的try语句。资源是指在程序用完了之后必须要关闭的对象。try-with-resources语句保证了每个声明了的资源在语句结束的时候都会被关闭。任何实现了java.lang.AutoCloseable接口的对象,和实现了java.io.Closeable接口的对象,都可以当做资源使用。

try (AutoCloseableTestClass autoCloseableTestClass = new AutoCloseableTestClass();
             AutoCloseableTestClass2 autoCloseableTestClass2 = new AutoCloseableTestClass2()
) {
     System.out.println("try{}");
} catch (Exception e) {
     e.printStackTrace();
 }

Java常用类库

Object类

1.Object类是所有的类的父类,是继承树上的根节点

2.除基本数据类型外所有对象都是Object

3.Object的方法是所有对象共有的

Object的常用方法

1.toString()方法 返回该对象的字符描述(类名+hash码)

2.hashCode()方法 返回该对象的哈希码(16进制的整数)

3.equals(obj)方法 判断对象是否与obj相等(没有重写的equals()方法相当于==操作符)

4.clone()方法 创建并返回一个对象的副本

equals()方法与==的区别

1.都可以艰辛对象的比较

2.==可以比较基本数据类型,而equals只能比较引用数据类型

3.语义上,==比较的是内存地址,不是同一地址比较结果一定为false

equals比较的是内容,如何比较取决于重写的规则,未重写之前equals与==没有区别

4.equals()方法用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断;

5."==" 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。

clone()方法

创建并返回一个对象的副本

clone需要重写才能使用

需要实现一个接口Cloneable(标志性接口,没有需要重写的抽象方法)

clone默认为浅克隆(基本数据类型数据在内存会有两份,引用数据类型克隆的对象和原对象共用一份)

深克隆(两个完全相同的对象,拥有两份完整的数据,需要自己重写实现)