文章目录
异常
概念
异常指在程序中出现的特殊情况
必要性
如果对于异常置之不理,就会导致程序的中断,甚至对程序造成毁灭性打击
分类
Throwable(可抛出的)
一切错误或异常的爸爸,无论是错误还是异常,都隶属与它
Error(错误)
JVM(一般为误删jdk或配置文件)、硬件、执行逻辑错误(概率最高)、不能手动处理(不能通过其他代码处理)
避免出现Error错误
Exception
程序在运行和配置中产生的问题,可处理
常见异常
异常 | 描述 |
---|---|
NullPointerException | 空指针异常 |
ArrayIndexOutOfBoundsException | 数组越界异常 |
ClassCastException | 类型转换异常 |
NumberFormatException | 数字格式化异常 |
ArithmeticException | 算术异常 |
异常的产生
自动抛出异常
当程序在运行时遇到不符合规范的代码或结果时,会产生异常
手动抛出异常(throw)
在可能发生的异常处添加语句throw new 异常类型(),这样抛出就需要在方法上声明可能要抛出的各种异常类型
语法:
throw new 异常类型("实际参数");
//手动抛出运行时异常
RuntimeException e = new RuntimeException("想抛出什么就写什么");
throw e;
示例:
public class A {
public static void main(String[] args) throws Exception {
int i = 2;
if (i % 2 == 0) {
throw new Exception("异常错误!");
}
}
}
### 异常产生后的结果 抛出异常后结束程序,相当于遇return语句 try{}catch(){}可以对于在异常抛出后不终止语句,到运行结束后再抛出
异常处理
try…catch()…
try{
//这里填可能出现异常的代码
}catch(Exception e){
//这里写异常产生后要怎么处理
//可以输出语句,不对异常进行抛出处理,这样就可以继续运行代码,但是不会进行定位点1以后的代码
//建议e.printStackTrace(),在代码全部运行结束后输出异常,会执行定位点1以后的代码
}
//定位点1
System.out.println("异常后的代码");
public class A {
public static void main(String[] args) throws Exception {
try {
int num = 1;
int a = 0;
int b = num / a;
System.out.println(b);
} catch (Exception e) {
e.printStackTrace();//可以执行后面的代码
}
System.out.println("hello word!");
int i = 2;
if (i % 2 == 0){
throw new Exception("异常错误!");//在这里已经抛出异常了
}
System.out.println("你好世界!");//不会被执行
}
}
//代码结果
/*
java.lang.ArithmeticException: / by zero
at com.wjs.properise.A.main(A.java:9)
Exception in thread "main" java.lang.Exception: 异常错误!
at com.wjs.properise.A.main(A.java:17)
hello word!
*/
案例(用户输入)
当程序需要用户输入一个int类型的数,而用户输入的是一个非数字类型的数时程序会自动抛出异常,那么我们可以把这个异常不执行,一直循环让用户输入数字为止
public class A {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int age;
while (true) {
System.out.println("请输入一个年龄:");
try {
age = scanner.nextInt();
System.out.println(age);
} catch (InputMismatchException e) {
System.out.println("输入有误,请重新输入!");
}
}
}
}
/*截截取片段
请输入一个年龄:
s
输入有误,请重新输入!
请输入一个年龄:
输入有误,请重新输入!
请输入一个年龄:
输入有误,请重新输入!
*/
这么做呢虽然不会爆出InputMismatchException(类型不匹配异常),但是会一直无限循环下去,不会给用户继续输入的机会。
- 原因很简单,在用户第一次输入不匹配值的时候,虽然对异常行为进行了处理
- 但是用户输入的值一直存储在缓存空间中当中(nextInt接收到的数据会存储在缓存空间中,没有任何变量接收时不会清理掉接收到的值,当接受的值赋值给变量时就会清理缓存空间的值),所以才会一直无限循环
- 所以处理方法就是清理缓存空间的值
- 在**System.out.println(“输入有误,请重新输入!”);**下行加上
- scanner.nextLine();
- 这样就可以清理缓存空间的值
多重catch
/*
子类异常在前,父类异常在后。
发生异常时按顺序逐个匹配。
只执行第一个与异常类型匹配的catch语句。
*/
public class A{
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int result=0;
try {
// String string=null;
// System.out.println(string.equals("hello"));
System.out.println("请输入第一个数字");
int num1=input.nextInt();//InputMismatchException
System.out.println("请输入第二个数字");
int num2=input.nextInt();
result=num1/num2;//发生异常// ArethmicException
}catch (ArithmeticException e) {//捕获 Exception:是所有异常的父类
System.out.println("算术异常");
}catch (InputMismatchException e) {
System.out.println("输入不匹配异常");
}catch (Exception e) {
System.out.println("未知异常");
}
System.out.println("结果是:"+result);
System.out.println("程序结束了...");
}
}
try…catch()…finally…
无论如何,finally{//执行语句}中的都会被执行
代码规范:
try {
//可能出现异常的代码
} catch(Exception e) {
//异常处理的相关代码,如:getMessage()、printStackTrace()
} finally{
//是否发生异常都会执行,可以释放资源等。
}
自定义异常
- 需继承Exception或Exception的子类,代表特定问题。
- 异常类型名称望文生义,可在发生特定问题时抛出对应的异常。
常用构造方法:
- 无参数构造方法。
- String message参数的构造方法。
6.2 异常中方法覆盖
带有异常声明的方法重写:
- 方法名、参数列表、返回值类型必须和父类相同。
- 子类的访问修饰符合父类相同或是比父类更宽。
- 子类中的方法,不能抛出比父类更多、更宽的检查时异常。
异常中方法覆盖
带有异常声明的方法重写:
- 方法名、参数列表、返回值类型必须和父类相同。
- 子类的访问修饰符合父类相同或是比父类更宽。
- 子类中的方法,不能抛出比父类更多、更宽的检查时异常。
public class Animal {
public void eat(){
System.out.println("父类吃方法..........");
}
}
public class Dog extends Animal{
@Override
public void eat() throw Exception{
//出现错误,父类没有声明异常,子类不能声明异常
System.out.println("子类的吃的方法..........");
}
}