Java之异常处理

什么是异常

导致程序的正常流程被中断的事件,叫做异常。
异常是程序中的一些错误,并不是所有的错误都是异常。

异常的分类

  • 可查异常: 可查异常即必须进行处理的异常,要么try catch住,要么往外抛,谁调用,谁处理,如果不处理,编译器,就不让你通过
  • 运行时异常: 运行时异常是可能被程序员避免的异常。与可查异常相反,运行时异常可以在编译时被忽略。
  • 错误: 指的是系统级别的异常,通常是内存用光了

其中,运行时异常和错误又叫非可查异常。

Exception 类的层次

所有的异常类是从 java.lang.Exception 类继承的子类。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
引用至菜鸟教程
(此图出自菜鸟教程)

异常的处理

异常处理常见手段: try-catch throw/throws

try-catch

先看一下报异常的:

package com.wr.internal;


import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class InternalApplicationTests {

    @Test
    public void contextLoads() {
        File file = new File("D:/exception.jpg");
        try {
            System.out.println("测试一下");
            new FileInputStream(file);
            System.out.println("走到这里啦");
        } catch (FileNotFoundException e) {
            System.out.println("报错啦:"+e.getMessage());
        }finally {
            System.out.println("走到这里啦==>finally");
        }
    }

}

// 这里是代码执行结果
测试一下
报错啦:D:\exception.jpg (系统找不到指定的文件。)
走到这里啦==>finally

再看一下没有报错的

package com.wr.internal;


import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class InternalApplicationTests {

    @Test
    public void contextLoads() {
        File file = new File("E:/微信图片_20191224172816.jpg");
        try {
            System.out.println("测试一下");
            new FileInputStream(file);
            System.out.println("走到这里啦");
        } catch (FileNotFoundException e) {
            System.out.println("报错啦:"+e.getMessage());
        }finally {
            System.out.println("走到这里啦==>finally");
        }
    }

}

// 这里是代码执行结果
测试一下
走到这里啦
走到这里啦==>finally

从结果中可以看到,在我们使用try-catch的时候,如果代码报了异常,报错的那行代码之后的语句都不会执行,它会进入到catch中。
还有一个关键字finally,无论代码有没有报错,它都会执行,所以我们一般会在finally语句块里运行清理类型等收尾善后性质的语句。

throw和thows

1、只使用throw关键字

package com.wr.internal;


import org.junit.Test;

import java.io.File;

public class InternalApplicationTests {

    @Test
    public void contextLoads() {
        test();
        System.out.println("走到这里啦");
    }

    private static void test() {
        System.out.println("测试一下");
        throw new RuntimeException("在这里抛出异常");
    }

}


//这里是结果
测试一下

java.lang.RuntimeException: 在这里抛出异常

	at com.wr.internal.InternalApplicationTests.test(InternalApplicationTests.java:18)
	at com.wr.internal.InternalApplicationTests.contextLoads(InternalApplicationTests.java:12)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

2、使用throw+try-catch

package com.wr.internal;


import org.junit.Test;

public class InternalApplicationTests {

    @Test
    public void contextLoads() {
        try {
            test();
            System.out.println("走到这里啦");
        } catch (Exception e){
            System.out.println(e.getMessage()+";这里处理一下");
        }
    }

    private static void test() {
        System.out.println("测试一下");
        throw new RuntimeException("在这里抛出异常");
    }

}

//这里是结果
测试一下
在这里抛出异常;这里处理一下

3、使用throws

package com.wr.internal;


import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class InternalApplicationTests {

    @Test
    public void contextLoads() {
        try {
            test();
            System.out.println("执行到这里");
        } catch (FileNotFoundException e) {
            System.out.println("报错啦:"+e.getMessage());
        }
    }

    private static void test() throws FileNotFoundException {
        File file = new File("D:/exception.jpg");
        System.out.println("测试一下");
        new FileInputStream(file);
    }

}


//这里是结果
测试一下
报错啦:D:\exception.jpg (系统找不到指定的文件。)

throws与throw这两个关键字接近,不过意义不一样,有如下区别:

  1. throws 出现在方法声明上,而throw通常都出现在方法体内。
  2. 一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
  3. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某个异常对象。

自定义异常

在 Java 中我们可以自定义异常。

  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个可查异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

定义一个异常类

package com.wr.internal;

/**
 * @Author: RainCity
 * @Date: 2022-03-12 11:42:19
 * @Desc:
 */
public class BaseException extends RuntimeException{
    private static final long serialVersionUID = -8792134760160960151L;

    /**
     * 错误码
     */
    private String code;

    /**
     * 错误消息
     */
    private String defaultMessage;

    public BaseException(String code, String message) {
        this.code = code;
        this.defaultMessage = message;
    }

    public String getCode() {
        return code;
    }

    public String getDefaultMessage() {
        return defaultMessage;
    }
}

测试一下

package com.wr.internal;


import org.junit.Test;

public class InternalApplicationTests {

    @Test
    public void contextLoads() {
        try {
            test();
            System.out.println("执行到这里");
        } catch (BaseException e) {
            System.out.println("报错啦:"+e.getCode()+";"+e.getDefaultMessage());
        }
    }

    private static void test() {
        System.out.println("测试一下");
        throw new BaseException("401", "在这里抛出异常");
    }

}


//这里是结果
测试一下
报错啦:401;在这里抛出异常

是不是很简单0.0
好了,到这就结束啦!!!

- -THE END- -

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值