异常
1 格式
try {
有可能异常的语句
}catch(异常类型 异常对象){
处理异常
}finally{
异常的出口
}
异常类型举例:
ArrayIndexOutOfBoundsException:索引越界
NullPointerException:空指针异常
catch可以捕获同时多个异常:异常间用 | 连接
catch(ArrayIndexOutOfBoundsException | NullPointerException ){
//....
}
Exception类是所有受查异常的父类,因此可以用这个类型表示捕获所有异常:
try{
//...
}
catch(Exception e){
e.printStackTrace; //打印错误路径
}finally{
//一定会执行
//一般用于关闭一些资源,
//如调用Scanner的close方法
}
注意:
将Scanner对象在try的()中创建,就能保证try执行完毕后自动调用Scanner的close方法
try(Scanner sc = new Scanner(System.in){
int num = sc.nextInt();
} catch (Exception e){
e.printStackTrace;
}
)
注意:
异常信息如果在异常发生处没有进行异常处理,那么异常信息就会向上传递,直到main函数中,如果还没有,则交给JVM处理,程序将报错终止;
异常信息主要看第一行。
2 使用throw抛出异常信息
使用throw手动抛出异常
public static int fun(int x){
if(x==0){
throw new ArithmeticException("抛出0异常")
}
return 10/x;
}
3 异常说明—throws
将可能发生的异常在方法定义的位置进行标注,用来提醒调用者要捕获这些异常
public fun(int x) throws ArithmeticException{
if(x==0){
throw new ArithmeticException("抛出0异常")
}
}
Throw 和throws 的区别:
- throws 用在函数上,后面跟的是异常类,可以跟多个 ;而throw 用在函数内,后面跟的 是异常对象。
public static void main(String[] args)
throws InterruptedException,IOException {
}
- throws 用来声明异常,让调用者知道该功能可能出现的问题,可以给出适当的处理方式;throw 抛出具体的问题对象,执行到throw,功能就已经结束了,跳转到调用者,并将具体的问题对象抛给调用者。也就是说throw 语句独立存在时,下面不要定义其他语句,因为执行不到。
- throws 表示出现异常的一种可能性,并不一定会发生这些异常; 执行throw 则一定会抛出某种异常对象。
- 两者都是消极处理异常的方式,只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的异常处理由函数的上层处理。
4 finally的注意事项
一般用来存放一些关闭资源的代码。
public static int func(){
try{
return 10;
}finally{
return 20;//finally尽量不要写return语句
}
}
finally的执行是在方法返回之前,如果try或catch中有return语句,那么会优先执行finally语句,(try中除了return语句,其余语句仍然优先执行),而碰巧finally中也有return语句,那么catch或try中的return语句就会得不到执行,但是除了return之外的语句都可以正常执行。
class Main{
public static int function(){
try{
System.out.println("hhh");
return 10;
}finally{
System.out.println("hhhhhhhh");
return 20;//finally尽量不要写return语句
}
}
public static void main(String[] args) {
System.out.println(function());
}
}
结果:
hhh
hhhhhhhh
20
5 异常体系Throwable->Error,Exception
Throwable 是Java 语言中所有错误或异常的超类。
-
顶层类Throwable派生出Error和Exception两个子类
-
Error
是指Java运行时内部错误和资源耗尽错误 -
Exception 有两个分支,一个是运行时异常RuntimeException ,一个是
CheckedException。 -
Exception的一个子类
RuntimeException
类和Error
类称为非受查异常(运行时异常),所有其他异常称为 (粉色)受查异常(编译时异常)
图片转自:https://www.nowcoder.com/questionTerminal/a4a96e226c7b4dafae8250db4ff88af5
Error :,如实例化错误,java.lang.InstantiationError,当一个应用通过new来实例化一个抽象类或接口时,抛出这个异常。
以及调用抽象方法时,也会抛出Error错误:java.lang.AbstractMethodError
下面展示一下资源耗尽错误:
public static void main(String[] args) {
ArrayList<Integer[]> list=new ArrayList<Integer[]> ();
int index=1;
for (int i=0;i<Integer.MAX_VALUE;i++){
list.add(new Integer[100000000]);
System.out.println("执行了第"+index+"次");
index++;
}
}
运行时异常 RuntimeException 如:NullPointerException 、ClassCastException 。RuntimeException 是那些可能在Java 虚拟机正常运行期间抛出的异常的超类。如果出RuntimeException,那么一定是程序员的错误.
受查异常 CheckedException :如I/O 错误导致的IOException、SQLException。一般是外部错误,这种异常都发生在编译阶段,Java 编译器会强制程序去捕获此类异常,即会出现要求你把这段可能出现异常的程序进行try catch,该类异常一般包括几个方面:
- 试图在文件尾部读取数据(IOException)
- 试图打开一个错误格式的URL
- 试图根据给定的字符串查找class 对象,而这个字符串表示的类并不存在(ClassNotFoundException)
注意:
- 受检查的异常(checked exceptions),其必须被 try{}catch语句块所捕获,或者在方法签名里通过throws子句声明.
6 异常的处理方式
(1)遇到问题不进行具体处理,而是继续抛给调用者(throw, throws
)
抛出异常有三种形式, throw, throws,还有一种 系统自动抛异常 。
如果不对异常进行声明或主动抛出,而让系统去直接抛出异常的情况,可能会对用户的体验不太友好。
(2)try catch
捕获异常进行针对性处理
7 自定义异常类—throw
class Myerror extends Exception{
public Myerror(String s){
super(s);//调用父类的构造方法
}
}
class Main{
static int passwd=0;
public static void login() throws Myerror{
if(passwd==0){
throw new Myerror("用户名错误");//主动抛出异常
}
}
public static void main(String[] args){
try{
login();
}catch(Myerror e){
e.printStackTrace();
}
}
}
结果:
Myerror: 用户名错误
at Main.login(Main.java:13)
at Main.main(Main.java:19)
注意:
- 继承自Exception的异常默认为受查异常
- 继承自RuntimeException的异常默认是非受查异常