异常概述
System.out.println(1/0);
System.out.println("呵呵");
//这段代码编译是可以通过的,但是运行的时候就出问题了,这种异常被称为运行时异常
//JVM帮我们捕获到异常
/*Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.xjt.demo01.ExceptDemo.main(ExceptDemo.java:5)
这一段报错信息中,前面告诉你出现了xxxx错误.
后一段告诉你在哪一行出的错误
*/
那么异常是如何产生的呢?
在运行到 1/0 的时候. 程序会创建一个异常对象对外抛出,然后被 JVM 捕获. JVM 也不知道怎么办. 就丢了出来,最终显示给用户了. 如果没有人处理异常, 程序会被中断. 这也是为什么我们没有看到”呵呵”两个字的原因
- 程序产生错误对象的过程被称为抛异常;
- 获取到这个错误信息. 被称为捕获异常;
异常分类
程序的错误千奇百怪,有的编译的时候就告诉你错了, 有的得运行起来才告诉你错了. 那我们就对异常进行分类.
分类之前, 我们想这么一个事儿,异常是错误对象,那有对象一定有类啊,对吧,异常类都有哪些呢?
异常类的根: Throwable
两个分支: Error 和 Exception
Exception 又分为 RuntimeException 和其他 Exception
RuntimeException 表示运行时异常
其他 Exception: 不用运行就知道错了
Error: 表示严重的问题 合理的应用程序不应该试图捕获. 程序员一般不好处理.
Error, Exception, RuntimeException 的区别:
RuntimeException: 运行时异常, 可以不用主动去处理. 就好比,开车上山, 路上很多的小石子, 不可能把每个小石子都处理掉吧. 等着小石子把轮胎扎破了. 再修就是了
Exception: 异常. 必须要手动处理. 还是开车上山, 路上突然出现一个大石头在前面. 你不把石头拿走. 你上不了山.
Error: 系统错误,这个就比较狠了。你开车上山 山塌了……你是解决不了的 只能避免 怎么避免? 换个山呗
区分编译时异常和运行时异常
补充:
编译时异常就是在 IDEA 等编译器中写的代码有异常时飘红,需要我们手动处理;
运行时异常,如 1/0 编译器不会飘红,但是运行时会报错;
如何查看某个异常属于编译时异常和运行时异常呢?
Throwable 成员方法
方法 | 描述 | 示例 |
---|---|---|
public String getMessage() | 返回此 throwable 的详细消息字符串 | public String getMessage() |
返回此 throwable 的详细消息字符串。
Index 3 out of bounds for length 3 |
| public void printStackTrace() | 将此 throwable 及其回溯打印到标准错误流。 此方法在错误输出流上打印此 Throwable 对象的堆栈跟踪,该字段为 System.err 字段的值。 第一行输出包含此对象的 toString()方法的结果。 剩余行表示先前由方法 fillInStackTrace()记录的数据。 此信息的格式取决于实现,但以下示例可能被视为典型: | java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at com.xjt.demo01.ExceptDemo.method(ExceptDemo.java:26)
at com.xjt.demo01.ExceptDemo.main(ExceptDemo.java:20) |
| public String toString() | 返回此 throwable 的简短描述,
结果是连接: 1)这个对象的类的 name
2)”:”(冒号和空格) 3)调用此对象的 getMessage()方法的结果 | java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 |
异常处理
try…catch…
示例:
public class ExceptDemo {
public static void main(String[] args) {
System.out.println("开始");
method();
System.out.println("结束");
}
public static void method(){
try {
int[] arr = {11,22,33};
System.out.println(arr[3]);
}catch (ArrayIndexOutOfBoundsException e){
e.printStackTrace();
System.out.println(e.getMessage());
System.out.println(e.toString());
}
}
}
打印结果:
开始
Index 3 out of bounds for length 3
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
结束
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at com.xjt.demo01.ExceptDemo.method(ExceptDemo.java:4)
at com.xjt.demo01.ExceptDemo.main(ExceptDemo.java:10)
try…catch…finally
try {
... //监视代码执行过程,一旦返现异常则直接跳转至catch,
// 如果没有异常则直接跳转至finally
} catch (SomeException e) {
... //可选执行的代码块,如果没有任何异常发生则不会执行;
//如果发现异常则进行处理或向上抛出。
} finally {
... //必选执行的代码块,不管是否有异常发生,
// 即使发生内存溢出异常也会执行,通常用于处理善后清理工作。
}
throws
有时候出现的异常时我们解决不了的,要通过 throws 将异常抛出去,由调用者解决(try…catch…)。
IDEA 工具使用 Alt+Enter 快速生成声明抛出异常 throws,
它运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常
使用格式:
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2 ... { }
throws 和 throw 的区别
自定义异常
示例:
//ScoreException.java
public class ScoreException extends Exception{
public ScoreException() {
}
public ScoreException(String message) {
super(message);
}
}
//MyDefineExcept.java
public class MyDefineExcept {
public void checkScore(int score) throws ScoreException {
if(score<0 || score>100){
throw new ScoreException("你给的分数有误,0<=score<=100");
}else{
System.out.println("分数正常");
}
}
public static void main(String[] args) {
MyDefineExcept mde = new MyDefineExcept();
try {
mde.checkScore(120);
} catch (ScoreException e) {
e.printStackTrace();
}
}
}