什么是异常
导致程序的正常流程被中断的事件,叫做异常。
异常是程序中的一些错误,并不是所有的错误都是异常。
异常的分类
- 可查异常: 可查异常即必须进行处理的异常,要么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这两个关键字接近,不过意义不一样,有如下区别:
- throws 出现在方法声明上,而throw通常都出现在方法体内。
- 一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
- 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- -