异常的概述和分类
程序员文章站
2022-04-21 17:56:54
...
异常的概述和分类
异常的概述:
异常就是java程序在运行时出现的错误。
异常的分类:
编译期异常:非RuntimeException。
运行期异常:RuntimeException及其子类,运行期异常我们自己可以解决,也可以不解决交由JVM 解决。JVM的默认处理方式是打印详细的异常信息,然后退出虚拟机。
自己处理运行期异常:
我们可以使用try catch 来进行异常的捕获处理
try 里面放的是你认为有可能会出现异常的代码。
catch(ArithmeticException e) catch 小括号里面定义的是,你将要捕获的何种异常。
catch 大括号里面 放的是,一旦发生你捕获的这种异常,你的处理方式是什么。
注意的有两点:
1.try里面尽可能放的是,有可能出现问题的代码。
2.一旦发生异常,异常的处理,不能空处理。
3.能明确的异常,尽量明确,不要拿Exception异常来明确。
4.捕获多个异常时,大的异常,放在最后面,平级关系的异常,谁前谁后无所谓。
案例:
1.JVM默认异常处理方式:
public class Test1 {
public static void main(String[] args) {
System.out.println(11/0);
System.out.println("之后的代码");
System.out.println("之后的代码");
}
}
结果:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Demo1.Test1.main(Test1.java:5)
Process finished with exit code 1
//如果使用JVM默认处理异常的机制,那么在处理完异常后,会直接关闭JVM,使得后续的代码无法运行。
2.使用Try{}catch(){}处理异常:
//在程序运行异常后,捕获异常,但是不会讲JVM终止,会继续执行后续代码。
代码:
public class Test1 {
public static void main(String[] args) {
try {
System.out.println(11/0);
}catch (ArithmeticException e){
System.err.println("除数为0了");
}
System.out.println("之后的代码");
System.out.println("之后的代码");
System.out.println("之后的代码");
}
}
结果:
除数为0了
之后的代码
之后的代码
之后的代码
Process finished with exit code 0
3.使用Try{}catch(){}处理多个异常:
代码:
public class Test1 {
public static void main(String[] args) {
int[] arr={1,2};
int[] arr1=null;
try {
//在try里面,如果出现代码运行期异常,则直接去catch找寻对应的异常。
System.out.println(arr[3]);
System.out.println(11/0);
System.out.println(arr1.length);
}catch (ArithmeticException e){
System.err.println("除数为0了");
}catch (ArrayIndexOutOfBoundsException e){
System.err.println("角标越界");
}catch (NullPointerException e){
System.err.println("空数组");
}
System.out.println("之后的代码");
System.out.println("之后的代码");
System.out.println("之后的代码");
}
}
结果:
角标越界
之后的代码
之后的代码
之后的代码
Process finished with exit code 0
案例:
//判断键盘录入的数据是否为需求的数据。
//如果不是,提醒重新输入。
public class Test2 {
public static void main(String[] args) {
while (true) {
Scanner sc = new Scanner(System.in);
try {
System.out.println("请输入一个整数:");
int i = sc.nextInt();
System.out.println(i);
break;
}catch (Exception e) {
System.out.println("输入的格式错误,请重新输入:");
}
}
}
}
结果:
请输入一个整数:
aa
输入的格式错误,请重新输入:
请输入一个整数:
ww
输入的格式错误,请重新输入:
请输入一个整数:
11
11
Process finished with exit code 0
throws和throw的区别
throws
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常
throw
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
这个异常对象可以是编译期异常对象, 可以是运行期异常对象
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常
案例:
public class Test3 {
public static void main(String[] args) throws ParseException {
int a = 10;
int b = 0;
double r = show(a, b);
System.out.println(r);
new SimpleDateFormat("yyyy-MM-dd").parse("2020-01-01");
}
private static double show(int a, int b) {
double r = 0;
if (b == 0) {
throw new ArithmeticException("除数为零,解析异常");
} else {
r = a / b;
}
return r;
}
}
结果:
Exception in thread "main" java.lang.ArithmeticException: 除数为零,解析异常
at Demo1.Test3.show(Test3.java:14)
at Demo1.Test3.main(Test3.java:7)
Process finished with exit code 1
自定义异常
为什么要有自定义异常?
Java给给我们提供了很多异常类,来描述我们在开发中所遇到一些常见的问题,
但是还是不足以,描述我们所遇到一些异常情况。
案例:银行取钱时,卡内余额不足
public class MyTest {
private static double money;
public static void main(String[] args) {
money = 100;
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你的取款金额");
double num = scanner.nextDouble();
quKuan(num);
}
private static void quKuan(double num) {
if(num<=money){
money-=num;
System.out.println("取款成功");
}else{
throw new NoMoneyException("余额不足异常");
}
}
}
class NoMoneyException extends RuntimeException {
public NoMoneyException(String msg) {
}
}
结果:
请输入你的取款金额
233
Exception in thread "main" Demo1.NoMoneyException
at Demo1.Test4.quKuan(Test4.java:23)
at Demo1.Test4.main(Test4.java:14)
Process finished with exit code 1
异常注意事项(针对编译期异常)
1.子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类,或者子类不抛出异常也是可以的。(父亲坏了,儿子不能比父亲更坏)
2.如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常,或者子类不抛出异常也是可以的。
3.如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
如何使用异常处理
原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这是用throws
区别:
后续程序需要继续运行就try
后续程序不需要继续运行就throws
如果JDK没有提供对应的异常,需要自定义异常。
下一篇: 强制隐藏软键盘终极办法