java异常机制

java 的异常机制主要依赖于 try、catch、finally、throw和throws这五个关键字

对于一个程序开发人员,需要尽可能地预知所有可能发生的情况,尽可能地保证程序在所有糟糕的情形下都可以运行

对于构造大型、健壮、可维护性的应用而言,错误处理是整个应用需要考虑的重要方面,程序员在开发程序的过程,是一个创造的过程,这个过程需要有全面的考虑,仅做“对”的事情是远远不够的

Java的异常处理机制可以让程序具有极好的容错性,让程序更加健壮,当程序出现意外情形时,系统会自动生成一个Exception对象来通知程序,从而实现将“业务功能实现代码”和“错误处理代码”分离,提供更好的可读性

1.使用try…catch捕获异常

 try{
     //业务实现代码
     ...
 } catch(Exception e) {
     
 }

如果执行try块里的业务逻辑时出现异常,系统自动生成一个异常对象,该异常对象被提交给java运行环境,这个过程被称为抛异常。

当java运行时环境收到异常消息时,会寻找能处理该异常对象的catch块,如果找到合适的catch块,则把该异常对象交给该catch块处理,这个过程被称为捕获异常,如果java运行时环境找不到捕获该异常的catch块,则运行时环境终止,程序就此退出。

2.异常类的继承体系
在这里插入图片描述

java把所有非正常的情况分为两种:异常(Exception)和错误(Error),它们都继承父类Throwable

Error错误一般指与虚拟机相关的问题,如系统崩溃、虚拟机错误等,这种错误无法恢复或不可捕获,将导致程序中断。通常应用程序无法处理这些错误,因此不应该试图使用catch块来捕捉Error对象。

进行异常捕获的时候不仅应该把Exception类对于的catch块放在最后,而且所有父类异常的catch块都应排在子类异常的catch块后面(简称:先处理小异常,再处理大异常),否则出现编译错误
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7mf3Ehlu-1625416839477)(7EAC4FF2A2844FD296A03E9B1D443082)]

java7提供多异常捕获,在java7之前,一个catch块只能捕获一种类型的异常,但从java7开始,一个catch块可以捕获多种类型的异常,使用时需要注意两点:

1.捕获多种异常类型时,多种异常类型之间用竖线(|)隔开

2.捕获多种异常类型时,异常变量有隐式的final修饰,因此程序不能对异常对象重新赋值

3.访问异常信息

当java运行时决定调用某个catch块来处理该异常对象时,会将异常对象赋给catch块后的异常参数,程序即可通过该参数来获得异常的相关信息

所有的异常信息都包含了如下几个常用方法:
- getMessage(): 返回该异常的详细描述字符串
- printStackTrace(): 将该异常的跟踪栈信息输出到标准错误输出
- printStackTrace(PrintStream s): 将该异常的跟踪栈信息输出到指定输出流
- getStackTrace():返回该异常的跟踪栈信息

4.Checked异常和Runtime异常体系

Java的异常被分为两大类:Checked异常和Runtime异常(运行时异常)。

所有的RuntimeException类及其子类的实例被称为Runtime异常;

不是RuntimeException类及其子类的异常实例被称为Checked异常

5.throws声明抛出异常

使用throws声明抛出异常的思路是:当前方法不知道如何处理该异常,该异常应由上一级调用者处理;如果调用方也不知道如何处理该异常,异常会向上一级抛出,该异常将交给JVM处理

JVM处理异常的方式是,打印异常的跟踪栈信息,并中止程序

throws声明抛出只能在方法定义中使用,throws可以声明抛出多个异常类,多个异常类之间以逗号隔开,throws声明抛出的语法格式如下:

throws ExceptionClass1, ExceptionClass2...

一旦使用了throws抛出该异常,程序就无需使用try…catch来捕获该异常了

6.throw抛出异常

当程序出现错误时,系统会自动抛出异常,除此之外,java也运行程序自行抛出异常,自行抛出异常使用throw语句来完成(注意此处的throw没有后面的s,注意区分throws)

如果throw抛出的异常是checked异常,则该throw语句要么处于try块里,显示捕获该异常,要么放在一个带throws声明抛出的方法中,即是将该异常交给调用者处理

如果throw语句抛出的异常是Runtime异常,则该语句无需放在try块里,也无需放在带throws声明的方法中

 public class ExceptionDemo {
    	//setHeight方法声明抛出HeightException异常,是Checked异常,所以调用该方法的代码要么处于try...catch块
    	//要么处于另一个带throws声明抛出的方法中
    	public void setHeight(int height) throws HeightException{
    		if (height < 0) {
    			throw new HeightException("身高 不可小于0");
    		}
    		System.out.println("身高为" + height);
    	}
    	
    	public static void main(String[] args) {
    		ExceptionDemo ex = new ExceptionDemo();
    		try {
    			ex.setHeight(-2);
    		} catch (HeightException e) {
    			e.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		System.out.println("身高设置完成");
    	}
    
        //自定义异常类
    	class HeightException extends Exception {
    		public HeightException(String exc){
    			System.out.println(exc);
    		}
    	}
    }

7.java的异常跟踪栈

异常对象的printStackTrace()方法用于打印异常的跟踪栈信息,根据printStackTrace()方法的输出结果,开发者可以找到异常的源头,并跟踪一路触发的过程

   	public class ExceptionDemo {
    	//setHeight方法声明抛出HeightException异常,所以调用该方法的代码要么处于try...catch块
    	//要么处于另一个带throws声明抛出的方法中
    	public void setHeight(int height) throws HeightException{
    		if (height < 0) {
    			throw new HeightException("身高 不可小于0");
    		}
    		System.out.println("身高为" + height);
    	}
    	
    	public static void main(String[] args) throws HeightException {
    		ExceptionDemo ex = new ExceptionDemo();
    		ex.setHeight(-2);
    		System.out.println("身高设置完成");
    	}
    
    
    	class HeightException extends Exception {
    		public HeightException(String exc){
    			System.out.println(exc);
    		}
    	}
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UrBZkyZM-1625416839479)(463E3EA316B547CFA8D67C4CD8719D1C)]

第一行的信息详细显示了异常的类型和异常的详细信息

接下来跟踪堆栈记录程序中所有发生的异常点,各行显示被调用方法中执行的停止位置,并标明类、类中的方法名、与故障点对应的文件的行。一行行地往下看,跟踪栈总是最内部的被调用方法逐渐上传,直至最外部业务操作的起点。

8.特别注意

主线程try...catch不能捕捉子线程的异常
   public class ThreadException extends Thread{
    	public void run() {
    		for(int i = 0; i < 30; i++) {
    			System.out.println(Thread.currentThread().getName() + "    " + i);
    			if (i == 10) {
    				System.out.println(1/0);
    			}
    		}
    	}
    	
    	public static void main(String[] args) {
    		System.out.println("::main()   " + Thread.currentThread().getName());
    		ThreadException ex = new ThreadException();
    		ex.start();
    		try {
    			ex.info();
    		} catch (Exception e) {
    			System.out.println(e.toString());
    		}
    	}
    	
    	public void info() {
    		System.out.println("::info()   " + Thread.currentThread().getName());
    		System.out.println(1/0);
    	}
    }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值