之前面试的时候被问到过关于异常的部分,做了一些整理
对于一段代码,如果认为可能出现问题,可以使用try catch处理
将认为可能出现问题的代码块选中,快捷键 ctrl+alt+t
在抛出异常后,程序时可以继续运行的。
异常分为两类:
Error:Java虚拟机无法解决的错误,肯定会崩溃,栈溢出,内存溢出等问题
Exception:运行时异常:程序运行时的异常
编译时异常:编写程序时,编译器检测出的异常
运行时异常:
NullPointerException【空指针异常】:当对象对象创建后没有赋值就开始使用
ArithmeticException【计算异常】:
ArrayIndexOutOfBoundsException【数组索引越界异常】:对数组进行操作时超过了数组实际的长度,数组下标为零
ClassCastException【类型转换异常】:父类可以接收子类,也可以转为子类,但是兄弟之间不可以转换。
NumberFormatException【数字格式异常】:程序将字符串转为整数(Integer.parseInt(str)),当该字符串不是数字时,会抛出该异常
异常处理机制:
try-catch-finally
try{
可能出问题的代码
如果发生了异常,那下面的代码不会执行,直接跳到catch
如果没有发生异常,则不会执行catch
}catch(Exception e){
异常发生时,系统将他封装成Exception对象传给对象e
再传递给catch,得到该异常后,可以根据自己的方式处理
}finally{
不管try代码块是否有异常发生,始终要执行
可以用来处理资源的关闭,资源的释放
}
- finally对于try-catch无论怎么执行,都始终会执行。
- 如果代码块有多个异常,可以有多个catch语句,用来捕获处理多种异常相应去做处理,子类异常写在父类异常的上面。
- 也可以不去使用catch,直接使用try-finally,就是指无论程序怎样都必须要执行的逻辑,执行完finally后程序依旧会停止又或者说崩掉,因为没有catch其实就是没有处理问题,所以该崩还是崩。
一个易错点(try-finally):
在try中一旦遇到抛出异常(throw)或者return的语句,会先执行finally,最后再去执行try中的throw或者return。但是如果finally中存在return的话,直接跳出,try中的也不会去执行。
throws:
扔问题给上一级,上一级可以选择再次抛给上一级或者try-catch处理,系统如果没有定义try-catch或者throws方法,都会默认throws抛给上一级,直到交给虚拟机,这也是为什么我们没有定义但是有打印异常信息的原因。
- 对于运行时异常,如果没有try-catch处理,默认throws处理
- 子类重写父类的的方法时,对于throws抛出的类型有要求,要么和父类抛出的一致,要么抛出的需要是父类抛出的异常子类。
比如父类throws Exception,那么子类重写该方法时,可以抛出Exception以及RuntimeException
当父类抛出的类型为RuntimeException,子类重写抛出的类型不可以是Exception
异常的传递机制:
运行时异常:其他方法调用抛出运行时异常的方法时,是可以不用处理的,因为存在默认的抛出机制(throws)。
编译异常:编译异常会传递,其他方法调用抛出编译异常的方法时,是必须使用try-catch或者throws处理的。
自定义异常
定义类: 自定义异常类名(程序员自己写) 继承Exception或RuntimeException
如果继承Exception,属于编译异常
如果继承RuntimeException,属于运行异常(一般来说,继承RuntimeException)
一般情况下,我们通常选择继承RuntimeException,这样我们可以使用默认处理机制,这样比较方便
throws和throw的对比:
throws:方法上 抛出异常类
throw:方法体内 抛出具体的异常