Java:异常处理

异常处理

异常是程序在执行过程中所产生的问题

异常是描述出错信息的对象

示例:

public static void main(String[] args) {
        method1();
    }


    public static void method1(){
        System.out.println("进入method1");
        method2();
        System.out.println("退出method1");
    }

    public static void method2(){
        System.out.println("进入method2");
        method3();
        System.out.println("退出method2");
    }


    public static void method3(){
        System.out.println("进入method3");
        int i = 1/0; //在java中除0会出现算法异常
        System.out.println("退出method3");
    }

控制台:

进入method1
进入method2
进入method3
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.lovo.com.lovo.classTest1.ClassTest.method3(ClassTest.java:25)
	at com.lovo.com.lovo.classTest1.ClassTest.method2(ClassTest.java:18)
	at com.lovo.com.lovo.classTest1.ClassTest.method1(ClassTest.java:12)
	at com.lovo.com.lovo.classTest1.ClassTest.main(ClassTest.java:6)

进程已结束,退出代码1
    
//Exception in thread "main"  表示出错的线程
//java.lang.ArithmeticException: / by zero   显示出错类型以及原因
/*
at com.lovo.com.lovo.classTest1.ClassTest.method3(ClassTest.java:25)
at com.lovo.com.lovo.classTest1.ClassTest.method2(ClassTest.java:18)
at com.lovo.com.lovo.classTest1.ClassTest.method1(ClassTest.java:12)
at com.lovo.com.lovo.classTest1.ClassTest.main(ClassTest.java:6)
	表示出错的位置
*/

异常的传播机制

当问题出现的时候,JVM会在出现问题的位置,产生一个描述问题产生原因的异常对象

首先,会在异常对象产生的位置,去查找有无异常解决方案,如果有则在此处解决,如果没有解决方案,异常产生位置的方法会从方法调用栈中弹出

然后将异常对象向方法调用栈下方的方法抛出,依此类推

直到最后异常对象会出现在main方法里面,如果main方法依然没有异常的解决方案,那么异常会导致main方法结束,然后在控制台中打印异常信息

异常控制流程

异常处理方法:

1、捕获这个异常,不让它沿着调用栈向下抛出

2、捕获这个异常,并继续向下抛出

3、不捕获这个异常,从而导致方法从调用栈中被弹出,异常对象继续抛给调用栈下方的方法

API结构和分类

API结构

Error:错误

a、应用程序不应该试图捕获的严重问题

b、可以捕获,不能处理

c、Error是所有错误类的父类

Exception:异常

a、指出了应用程序想要捕获的条件

b、可以捕获,可以处理

c、Exception是所有异常类的父类

Throwable类

两个方法,获取抛出异常的信息

public String getMessage();

public void printStackTrace();

分类

编译期异常(检查异常)

开发者必须处理,否则无法通过编译

运行期异常(非检查异常)

开发这可以处理,也可以不处理,即使不处理也可通过编译

所有运行期异常都是**RuntimeException**的子类

异常处理

异常捕获

三者不能独自使用,必须组合

try

书写可能会抛异常的代码,在其中尝试运行

catch

真正意义上的捕获

finally

无论try块中是否有异常都会执行的代码

一般用于资源清理工作,比如:流的关闭,数据库的关闭等

代码层面上:

``try``和``catch``中的``return``不影响``finally``的执行

只有``System.exit(0);``  会导致其代码不执行

int x = 9;
try{
	return x;
}catch(){
	
}finally{
	x += 2;
}
/*
	最终返回的是9
	当程序遇到return语句时,不是马上执行finally中的语句
	先把return的准备工作做完,包含了返回值的准备(此时是9)
	然后再执行finally块中的代码
	finally执行完毕后直接进行流程的返回
	虽然在finally中对x进行了改变,但是不影响之前return准备好的返回值
*/

代码格式(含组合)

try{
	可能会抛出异常的代码
}catch(要处理的异常类 对象){
	处理异常的代码
}finally{
	不管是否发生异常都会执行的代码,除非虚拟机关闭
}
try{
	可能会抛出异常的代码
}catch(要处理的异常类 对象){
	处理异常的代码
}
try{
	可能会抛出异常的代码
}finally{
	不管是否发生异常都会执行的代码,除非虚拟机关闭
}
/*
 此时不会捕获异常,没有处理,比较鸡肋
*/

例子

try{
	int i = 1/0;
}catch(ArithmeticException e){
	e.printStackTrace(); //通过方法调用栈,得到整个错误信息
	System.out.println(e.getMessage()); //可省略
}finally{
	System.out.println("不管是否发生异常都会执行的代码");
}

捕获或处理的执行顺序

没有异常时

如果try块中没有抛出异常,那么catch块将被忽略,执行finally块

有异常时

先顺序执行try块中的代码

如果try块中出现异常,终止try块剩余代码的执行

直接跳转到与异常类型匹配的catch块中

执行异常处理的代码,再执行finally里面的代码

多catch

JDK7以后出现

  • 多个catch里最多被执行一个

  • 写在前方的catch捕获的异常类型不能是后面异常类型的父类

异常抛出

开发者可通过throw和throws关键字抛出异常

throw和throws可以不用捆绑出现

throw

用于抛出异常对象

throw new Exception(); // 抛出一个编译期异常
throw new RuntimeException();//抛出一个运行期异常

例子

throw new RuntimeException();

throws

属于方法声明

- 此时方法重写的规范需要加一条:

  重写之后的方法不能比重写之前的范围大(运行期异常除外)

标识该方法可能会抛出某种异常

public void test() throws Exception{
	
}

例子

public static void main(String[] args) {
        testThrow(null);
    }

public static void testThrow(String str) throws RuntimeException{
        if (str == null){
            RuntimeException exception = new RuntimeException();
            //人为抛出异常
            throw exception;
        }
    }


//控制台
Exception in thread "main" java.lang.RuntimeException
	at com.lovo.com.lovo.classTest1.ClassTest.testThrow(ClassTest.java:43)
	at com.lovo.com.lovo.classTest1.ClassTest.main(ClassTest.java:8)

进程已结束,退出代码1

如何编写自定义异常

1、创建一个类继承于Exception / RuntimeException
2、添加一个带参构造方法和普通方法

public class MyException extends Exception{
	public MyException(String message){
		super(message);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值