一、异常
1. 什么是异常
异常是程序在运行期发生的不正常的事件,它会打断指令的正常执行流程。
2.异常的由来
通过java的类的形式对现实事物中问题的描述,并封住成了对象。其实就是java对不正常情况描述后的对象体现。
3.常见的异常类
算术异常类 | ArithmeticExecption |
---|---|
空指针异常类 | NullPointerException |
类型强制转换异常 | ClassCastException |
数组负下标异常 | NegativeArrayException |
数组下标越界异常 | ArrayIndexOutOfBoundsException |
违背安全原则异常 | SecturityException |
文件已结束异常 | EOFException |
文件未找到异常 | FileNotFoundException |
字符串转换为数字异常 | NumberFormatException |
操作数据库异常 | SQLException |
输入输出异常 | IOException |
方法未找到异常 | NoSuchMethodException |
抽象方法错误,当应用试图调用抽象方法时抛出 | java.lang.AbstractMethodError |
二、异常的分类
1.异常的超类和相关子类
throwable.jpg①Throwable是所有异常的根,java.lang.Throwable
②Error是错误,java.lang.Error
③Exception是异常,java.lang.Exception
2. Exception和RuntimeException
Java中的异常被分为两大类:编译时异常和运行时异常。所有的RuntimeException类及其子类的实例被称为运行时异常,其他的异常就是编译时异常。
3.异常例子:1除数为0, 2 数组访问越界
除数为0:
JVM发现运算是已经违反了数学运算规则,java将这种常见的问题进行描述,并封装成了对象叫ArithmeticException。当除0运算发生后,jvm将该问题打包成了一个异常对象.并将对象抛给调用者main函数,new ArithmeticException("/by zero");
public static void main(String[] args) throws ArithmeticException {
//分子
int a=3;
// 分母
int b=0;
int result = a/b;
System.out.println(result);
}
运行结果:
数组访问越界:
访问的数组下标不存在。
public static void main(String[] args) {
int [] a={1,2,3};
System.out.println(a[4]);
}
运行结果:
三、异常的处理
1. JVM的默认处理方法
代码抛出异常JVM会帮我们创建对象,抛出异常类型。
案例:
public static void main(String[] args) throws NumberFormatException {
//不是纯数字字符串
String b = "hello";
//数字转换异常
System.out.println(Integer.parseInt(b));
}
运行结果:
2.一个异常的情况
使用try…catch…finally处理异常。
基本格式:try是检测异常,catch是用来捕获异常的,finally是用来结束资源的。世界上最真情的相依,是你在try我在catch,无论你发神马脾气,我都默默接受,静静处理采用RuntimeException。
案例
public static void main(String[] args) {
try {
int [] a={1,2,3};
System.out.println(a[4]);
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}finally {
System.out.println("一定会执行的逻辑");
}
}
3.多个异常的情况分情况考虑
1. 每一个写一个try...catch
2. 写一个try,多个catch
try{
...
}catch(异常类名 变量名) {
...
}catch(异常类名 变量名) {
...
}
...
案例:
public static void main(String[] args) {
try {
int [] a={1,2,3};//定义一个数组
int[] b=null;//定义一个null数组对象
//打印结果
System.out.println(a[4]);//报数组下标越界
System.out.println(b.length);//报空指针异常
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
*注意:
一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,然后结束了try...catch继续执行后面的语句。
4. 父子类异常注处理意事项
public class Father {
public void xxx() {
}
}
public class Child extends Father {
//子类抛出异常只能是父类抛出相同异常或父类抛出的异常子类
@Override
public void xxx() throws Exception {
super.xxx();
}
}
- 能明确的尽量明确,不要用大的来处理。
- 平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。
- 父类的xxx方法没有抛出异常,子类抛出异常只能是父类抛出相同异常或父类抛出的异常子类。
四、编译时异常和运行时异常的区别
编译时异常:
Java程序必须显示处理,否则程序就会发生错误,无法通过编译。
运行时异常:
无需显示处理,也可以和编译时异常一样处理。
五、超类Throwable中的相关方法
//获取异常信息,返回字符串
getMessage()
//获取异常类名和异常信息,返回字符串
toString()
//获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。获取异常所有信息
printStackTrace()
//通常用该方法将异常内容保存在日志文件中,以便查阅
//参数:打印流
printStackTrace(PrintStream s)
六、java提供的其他异常处理方案
1. throws的特点和注意事项
有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。 为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
格式:
throws 异常类名 ,这个格式必须跟在方法的括号后面。
*注意:
尽量不要在main方法上抛出异常。
但是我讲课为了方便我就这样做了。
小结:
编译期异常抛出,将来调用者必须处理。
运行期异常抛出,将来调用可以不用处理。
2. throw的特点和注意事项
如果出现了异常情况,我们可以把该异常抛出,这个时候的抛出的应该是异常的对象。
3. throws和throw的区别
throws:
1. 用在方法声明后面,跟的是异常类名
2. 可以跟多个异常类名,用逗号隔开
3. 表示抛出异常,由该方法的调用者来处理
4. throws表示出现异常的一种可能性,并不一定会发生这些异常
throw:
1. 用在方法体内,跟的是异常对象名
2. 只能抛出一个异常对象名
3. 表示抛出异常,由方法体内的语句处理
4. throw则是抛出了异常,执行throw则一定抛出了某种异常
4. finally的特点作用
finally的特点:
1.被finally控制的语句体一定会执行
- 特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))
finally的作用:
- 用于释放资源,在IO流操作和数据库操作中会见到
5.自定义异常方案
考试成绩必须在0-100之间:很明显java没有对应的异常,需要我们自己来做一个异常。
自定义异常:
继承自Exception,或者继承自RuntimeException。
案例
/**
* 自定义异常
*/
public class MyException extends Exception {
//无参构造
public MyException() {
}
//有参构造
public MyException(String message) {
super(message);
}
}
public static void main(String[] args) throws MyException {
//考试成绩必须在0-100之间
int score =110;
if (score>=0&&score<=100){
System.out.println(score);
}else{
throw new MyException("考试成绩必须在0-100之间");
}
}
运行结果:
P2-03.png七、异常注意事项
1.子类重写父类方法时有什么特点
子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
2.父类抛出多个异常会有什么情况
如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
3. 如果被重写的方法没有抛出异常那么子类有什么变化
- 能明确的尽量明确,不要用大的来处理。
- 平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。
网友评论