Java语言中,将程序执行中发生的不正常情况称为“异常”.(开发过程中的语法错误和逻辑错误不是异常)
快捷键: ctrl+alt+t
,选中try-catch
执行过程中的异常可以分为两大类:
Error
(错误):Java虚拟机无法解决的严重问题。比如:JVM
系统内部错误,资源耗尽等严重情况。比如:StackOverFlowError
和OOM(out of memory),Error
是严重错误,程序会崩溃。Exception
:其他因为编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等等。Exception
分为两类:运行时异常和编译时异常这里画了一些常见经典的异常。
总结:
java.lang.RuntimeException
类以及它的子类都是运行时异常。常见的运行时异常(RuntimeError)
NullPointerException
空指针异常ArithmeticException
数字运算异常ArrayIndexOutOfBoundsException
数组下标越界异常ClassCastException
类型转换异常NumberFormatException
数字格式不正确异常编译异常实在编译期间,就必须处理的异常,否则代码不能通过编译。
常见的编译异常有:
SQLException
操作数据库,查询表可能发生异常IOException
操作文件时,发生的异常FileNotFoundException
当操作一个不存在的文件时,发生的异常EOFException
操作文件,到文件末尾,发生异常IllegalArguementException
参数异常异常处理就是当异常发生事,对异常处理的方式
异常处理的方式:
try-catch-finally
程序元在代码中捕获发生的异常,自行处理
处理机制:
try{
代码/可能有异常
}catch(Exception e){
//捕获异常
//1、当异常发生时
//2、系统将异常封装成Exception对象e,传递给catch
//3、得到异常对象后,程序员,自己处理
//4、注意,如果没有发生异常,catch代码块不执行
}finally{
//1、不管try代码块是否有异常发生,始终要执行finally
//2、所以,通常将释放资源的代码,放在finally
}
throws
将发生的异常抛出,交给调用者(方法)来处理,最顶级的就是JVM
处理机制:
try-catch
方式处理异常注意事项如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch
块
如果异常没有发生,则会顺序执行try
里面的代码块,不会进入到catch
如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用finally
可以有多个catch
,捕获不能的异常(进行不同的业务处理),要求父类异常在后面,子类异常前面(比如:Exception
在后,NullPointerException
在前,如果发生异常,只会匹配一个catch
举例:
public class TryCatchDetail01 {
public static void main(String[] args) {
//多个异常,可以多个catch,但是要求子类写在前面,父类写在后面
try {
Person person = new Person();
System.out.println(person.getName()); //空指针异常
int n1 = 10;
int n2 = 0;
int res = n1/n2; //算术异常
} catch (NullPointerException e){
System.out.println("空指针异常"+e.getMessage());
}catch (ArithmeticException e){
System.out.println("算术异常"+e.getMessage());
}
catch (Exception e) {
System.out.println(e.getMessage());
} finally {
}
}
}
class Person{
private String name;
public Person() {
}
public String getName() {
return name;
}
}
可以进行try-finally
配合使用,这种相当于没有捕获异常,程序会直接崩溃。应用场景,执行一段代码,不管是否发生异常,都会执行某个业务逻辑。
try{
//可能发生的语句
}finally{
//必须执行的
}
举例:
// public void f2() throws FileNotFoundException{
// public void f2() throws FileNotFoundException, NullPointerException, ArithmeticException{
public void f2() throws Exception{
//抛出异常,让调用f2的调用者进行处理
//throws后面可以是当前异常的父类,也可以抛出多个异常
FileInputStream fis = new FileInputStream("d://aa.txt");
}
}
throws
处理throws
的过程中,如果有方法try-catch
,就相当于处理异常,可以不用throws
举例:
public class ThrowsDetails {
public static void main(String[] args) {
}
public static void f1(){
//运行时异常,会默认throws
f2();
}
public static void f2() throws NullPointerException{
}
public static void f3() throws Exception{
//而编译类型的异常必须进行处理,否则会报错,调用者抛出的异常可以是之前的异常,或者之前的异常的父类
f4();
}
public static void f4() throws FileNotFoundException {
}
}
class A{
public void f1() throws Exception{
}
}
class B extends A{
@Override
//子类抛出的异常必须是父类的子类或者父类的异常
public void f1() throws NullPointerException {
}
}
当程序中出现了某些错误,但是该错误信息并没有在Throwable
的子类中描述处理,这个时候可以自己设计异常类,用于描述该错误信息。
Exception或者RuntimeException
Exception
,属于编译异常RuntimeException
,属于运行异常,一般来说都是继承RuntimeException
举例:
//自定义一个异常
//一般情况下,都是自定义为运行时异常,RuntimeException,这样可以使用默认的处理机制
class AgeException extends RuntimeException{
public AgeException(String message) {//构造器
super(message);
}
}
意义 | 位置 | 后面跟的东西 | |
---|---|---|---|
throws | 异常处理的方式 | 方法声明处 | 异常类型 |
throw | 手动生产异常对象的关键字 | 方法体中 | 异常对象 |
举例:
public class CustomException {
//throws
public static void main(String[] args) throws Exception{
int age = 180;
if(!(age >= 18 && age <= 120)){
//这里可以根据构造器,设置信息
//throw
throw new AgeException("年龄需要在18和120之间");
}
System.out.println("年龄范围正确");
}
}