文章目录
java-异常查询表
一. 异常的概念
什么是异常
程序在运行过程中出现的非正常的情况,最终会导致JVM的非正常停止。
在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
二. Throwable体系
- Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。
- |-Error:JVM、硬件、执行逻辑错误,不能手动处理。只能事先避免。
- |-Exception:程序在运行和配置中产生的问题,可处理。
- |-RuntimeException:运行时异常,可处理,可不处理。
- |-CheckedException:编译时异常(受查异常),必须处理。
public class Test1 {
public static void main(String[] args) {
test(); // error
}
public static void test() {
String string= "";
string += string;
test();
}
}
Exception in thread “main” java.lang.StackOverflowError
public class Test2 {
public static void main(String[] args) {
Integer.parseInt("abc");//Exception
}
}
Exception in thread “main” java.lang.NumberFormatException: For input string: “abc”
public class Test3 {
public static String tempString;
public static void main(String[] args) {
System.out.println(tempString.equals(""));
}
}
Exception in thread “main” java.lang.NullPointerException
public class Test4 {
public static void main(String[] args) {
String[] string = new String[10]; // java.lang.ArrayIndexOutOfBoundsException
for (int i = 0; i <= string.length; i++) {
System.out.println(string[i]);
}
}
}
Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 10
受查异常
三. 异常的产生
自动抛出异常:
当程序在运行是遇到不符合规范的代码或结果时,会产生异常。
手动抛出异常:throw
语法:
throw new 异常类型("实际参数");
throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
【注】:
- throw关键字必须写在方法内。
- throw关键字后面new的对象必须是Exception或Exception的子类对象
- throw关键字抛出的异常对象
- 如果是RuntimeException或其子类对象,则可以不处理;
- 如果不是,则必须处理。
- 一种是进行捕获处理。try…catch…
- 另一种就是使用throws继续将问题声明出去。
四. 异常的传递
异常的传递:按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认 异常处理(打印堆栈跟踪信息)。 e.printStackTrace();
受查异常:throws 声明异常,修饰在方法参数列表后端。用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。
格式:
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
【注】:
- 编译时异常有两种处理方案:try…catch …或者 throws,如果采用 throws 这种方案,将来谁调用谁处理
- 运行时异常可以不处理,出现问题后,需要我们回来修改代码
运行时异常:因可处理可不处理,无需声明异常。
【例】:异常的传递 & throws
public class Test1 {
public static void main(String[] args) {
t1();
}
public static void t1() {
t2();
}
public static void t2() {
t3();
}
public static void t3() {
Integer.parseInt("abc");
}
}
public class Test1 {
public static void main(String[] args) {
try {
t1();
} catch (Exception e) {
System.out.println("有问题...");
// e.printStackTrace();
}
System.out.println("// 继续执行下面的代码");
}
public static void t1() throws Exception {
t2();
}
public static void t2() throws Exception {
t3();
}
public static void t3() throws Exception {
Integer.parseInt("abc");
}
}
![image-20200813154120836](https://i-blog.csdnimg.cn/blog_migrate/fdab1a7bc66504501bb3398e3e3eef40.png)
五. 异常的处理
关键字
Java异常处理的五个关键字:try、catch、finally、throw、throws
try…catch…(finally…)结构
try {
可能出现异常的代码
} catch(Exception e) {
异常处理的相关代码
// 如:getMessage()、printStackTrace()、toString()
} finally {
无论是否出现异常,都需执行的代码结构
// 常用于释放资源。
}
执行流程:
- 程序从 try 里面的代码开始执行
- 出现异常,就会跳转到对应的 catch 里面去执行
- 执行完毕之后,程序还可以继续往下执行
【注】:
- try和catch都不能单独使用,必须连用。
- finally不能单独使用。必须和try一起使用
- 如果finally有return语句,永远返回finally中的结果,尽量避免该情况。(详见【附例1】)
- 父类异常什么样,子类异常就什么样。(详见【附例2】)
- 如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。
- 父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
【附例1】
public class Demo01 {
public static void main(String[] args) {
int a = getA();
System.out.println(" a = " + a);
}
public static int getA() {
int a = 10;
try {
return a;
} catch (Exception e) {
System.out.println(e);
} finally {
a = 100;
return a;
}
}
}
运行结果:
a = 100
【附例2】
public class Super {
public void show01() throws NullPointerException,ClassCastException{}
public void show02() throws IndexOutOfBoundsException{}
public void show03() throws IndexOutOfBoundsException{}
public void show04() throws Exception {}
}
class Sub extends Super{
//子类重写父类方法时,抛出和父类相同的异常
public void show01() throws NullPointerException,ClassCastException{}
//子类重写父类方法时,抛出父类异常的子类
public void show02() throws ArrayIndexOutOfBoundsException{}
//子类重写父类方法时,不抛出异常
public void show03() {}
/*
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。
*/
//public void show04() throws Exception{}
//此时子类产生该异常,只能捕获处理,不能声明抛出
public void show04() {
try {
throw new Exception("编译期异常");
} catch (Exception e) {
e.printStackTrace();
}
}
}
常见的异常处理结构
try {} catch {}
try {} catch {} catch {}
try {} catch {} finally {}
try {} catch {} catch {} finally {}
try {} finally {}
【注】:多重catch,遵循从子(小)到父(大)的顺序,父类异常在最后。
【快捷键】:Alt + Shift + Z
throws和throw的区别
throws
- 用在方法声明后面,跟的是异常类名
- 表示抛出异常,由该方法的调用者来处理
- 表示出现的一种可能性,并不一定会发生这些异常
throw
- 用在方法体内,跟的是异常对象名
- 表示抛出异常,由方法体内的语句处理
- 执行throw 一定抛出了某种异常
【例】:getMessage()、printStackTrace()、toString()的不同
public class ExceptionDemo02 {
public static void main(String[] args) {
System.out.println("开始");
method();
System.out.println("结束");
}
public static void method() {
try {
int[] arr = {1, 2, 3};
System.out.println(arr[3]); //new ArrayIndexOutOfBoundsException();
System.out.println("这里能够访问到吗");
} catch (ArrayIndexOutOfBoundsException e) { //new ArrayIndexOutOfBoundsException();
//System.out.println("调用e.printStackTrace()"); // 方法一
//e.printStackTrace(); // public void printStackTrace():把异常的错误信息输出在控制台
//=========================================================
//System.out.println("调用e.getMessage()"); // 方法二
//System.out.println(e.getMessage()); // public String getMessage():返回此 throwable 的详细消息字符串
//=========================================================
//System.out.println("调用e.toString()"); // 方法三
//System.out.println(e.toString()); // public String toString():返回此可抛出的简短描述
//=========================================================
}
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6282ce50101b09185262b5cfbf57d0b4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1a54ecf8228f6312d0b4541ffb297ed4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f1bacf246244193d10f4ff8e98e9b8c4.png)
六. 自定义异常
在开发中总是有些异常情况是JDK内部没有定义好的,例如年龄负数问题,考试成绩负数问题等等。因此需要根据自己业务的情况来自定义异常类。
概念:需继承Exception或Exception的子类,代表特定问题。
经验:异常类型名称望文生义,可在发生特定问题时抛出对应的异常。
常用构造方法:
- 无参构造方法
- String message参数的构造方法
方法重写
- 方法名、参数列表、返回值类型必须和父类相同。
- 子类的访问修饰符和父类相同或比父类更宽。
- 子类中的方法,不能抛出比父类更多、更宽的异常。
【例】:自定义异常
自定义异常类
public class ScoreException extends Exception {
public ScoreException() {}
public ScoreException(String message) {
super(message);
}
}
老师类
public class Teacher {
public void checkScore(int score) throws ScoreException {
if(score<0 || score>100) {
// throw new ScoreException();
throw new ScoreException("你给的分数有误,分数应该在0-100之间");
} else {
System.out.println("成绩正常");
}
}
}
测试类
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入分数:");
int score = sc.nextInt();
Teacher t = new Teacher();
try {
t.checkScore(score);
} catch (ScoreException e) {
e.printStackTrace();
}
}
}
总结
- 异常的概念:
- 程序在运行过程中出现的特殊情况。
- 异常的分类:
- RuntimeException:运行时异常,可处理,可不处理。
- CheckedException:受查异常,必须处理。
- 异常的产生:
- throw new 异常类型(“实际参数”);
- 相当于遇到return语句,导致程序因异常而终止。
- 异常的传递:
- 按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。
- 异常的处理:
- try {} catch {} finally {}
- 带有异常声明的方法重写:
- 子类中的方法,不能抛出比父类更多、更宽的异常。