异常体系
Java把异常也封装成为了对象
NullPointerException 空指针异常
ClassCastExceptio 类型转换异常
ArrayIndexOutOfBoundsException
关键字throw和throws
-
throw的作用和return很像
return的作用是方法返回,并且可以根据返回值类型返回相应的变量
throw的作用也是方法返回,但是只能返回异常对象,也就是说throw后面跟的对象必须是Throwable的子类创建的
调用方的代码处于上层,被调用方的代码处于下层
上层代码调用下层代码的时候
下层可以同时有正常返回和异常返回两种返回方式
下层可以没有任何范围
下层可以只有正常返回
下层可以只有异常返回
下层方法中正常返回用return
下层方法中异常返回(抛出)用throw
上层接收下层正常返回的语法的结果是:
数据类型 变量 = 方法();
- 变量用于接收下层方法的返回值,它的数据类型必须与下层方法中的返回值类型一样或者兼容
- 上层接收下层异常抛出的对象的语法是:
try......catch 是一种特殊的分支语句
try{
数据类型 变量 = 方法(;)
}catch(数据类型 变量){
}
上层代码接收下层代码的返回值
上层代码捕捉下层代码的异常
正常返回 | 异常返回 |
下层是返回 | 下层是抛出 |
上层是接收 | 上层是捕捉 |
异常对象中有什么?
1.异常信息
下层代码构造异常对象的时候,可以在构造方法中传入一个String类型的异常信息,这个异常信息会存储在Throwable中的detailMessage成员变量中,上层代码在捕捉到异常对象后可以使用getMessage()读取到下层返回的异常信息
2.打印异常的追踪栈信息
当下层代码构造异常对象对象的时候,会创建一个栈,存储本次代码执行过程中所涉及到的所有的方法信息,这些信息包括:1.方法入栈执行的先后顺序;2.出异常的代码在哪个
1.以后调用方法的时候,方法下面出现一条红线,确认没有语法错误,那就一定是要你捕捉异常
未处理的异常
什么是NPE,为什么会发生NPE
NullPointerException,空指针异常,返回数据为null的值
为什么会发生NPE:本身引用的内容是空的,比如获取一个对象的值,但是这个对象在逻辑中没拿到值,变成了null
- 如何避免NPE问题:在调用变量之前做null值的判断,避免调用null值。
什么是OOM,为什么会发生OOM
OOM:Out Of Memory,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:非exception,因为这个问题已经严重到不足以被应用处理)。
为什么会OOM?
1.分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。
2.应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。
内存泄露:申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了,因为申请者不用了,而又不能被虚拟机分配给别人用。
内存溢出:申请的内存超出了JVM能提供的内存大小,此时称之为溢出。
throw和throws的区别
1、
throw代表动作,表示抛出一个异常的动作;
throws代表一种状态,代表方法可能有异常抛出
throw用在方法实现中,而throws用在方法声明中;
throw只能用于抛出一种异常,而throws可以抛出多个异常
2、
throw关键字用来在程序中明确的抛出异常,相反 throws语句用来表明方法不能处理的异常。
每一个方法都必须要指定哪些异常不能处理,所以方法的调用者才能够确保处理可能发生的异常,多个异常是用逗号分隔的。
3、
throw是在代码块内的,即在捕获方法内的异常并抛出时用的
throws是针对方法的,即将方法的异常信息抛出去
可以理解为throw是主动(在方法内容里我们是主动捕获并throw的),而throws是被动(在方法上是没有捕获异常进行处理,直接throws的)
throw和return的区别
throw,作用会一层一层往上抛出 最终抛向虚拟机,而throw指抛出异常,并且该方法以及调用该方法的一切方法将不会向下执行
return的作用很简单,意思是方法直接返回了,该方法不在向下执行。但是调用该方法的方法继续执行。
Try-catch-finally中哪一部分可以省略
Try不可以省略
Catch可以省略
Finally可以省略
catch和finally不可以同时省略
Try-catch:try中发生的异常被catch捕捉,程序可以继续往后运行
Try-finally:try中发生的异常没有被程序捕捉,程序会立即退出,但退出之前会执行finally
Try-catch-finally:try中发生异常,异常代码后面的代码不会执行,直接进入catch,try中没有发生异常,不会进入catch,无论是否发生异常,finally都会执行。
一般在finally块中做什么
在try-catch-finally语法中,无论执行try还是catch,最终都会执行finally,所以我们一般把在try中打开的资源放在finally中进行释放。
例如:在try中创建了数据库连接,在finally中关闭
在try中创建了IO流,在finally中关闭
try-catch-finally中,如果catch中return了,finally还会执行吗
finally会在return之前执行,但是finally中无法改变返回值结果
可以理解为执行return的时候,先确定下返回值,但方法还没有出栈,然后执行finally,如finally中改变了返回的变量的值, 也不会对最终返回值产生影响,
异常体系整理
什么是异常处理
- 异常是被调用方向调用方传递错误信息的一种途径, 当被调用方的方法在执行过程中出现了问题, 可以通过抛出异常对象, 让调用方捕捉从而实现错误信息的传递。
- 使用异常机制可以保证程序代码更加优雅,并提高程序健壮性。
- 被调用方抛出的异常对象能清晰的向调用方反应what, where, why这3个问题:
异常类型反应了“什么”被抛出
异常堆栈跟踪反应了“在哪”抛出
异常信息反应了“为什么”会抛出
Java异常体系类图
Exception和Error的区别
Exception和Error同属于Throwable的直接子类, 是2个体系
Exception 体系的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行。
Error体系的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测, 我们也不需要对这类错误进行捕获处理(因为你捕捉了也没用), 一旦这类错误发生, 应用程序会被终止。
Exception和RuntimeException的区别
RuntimeException是Exception的子类
Exception是受检的, 称为编译时异常
RuntimeException是不受检的, 称为运行时异常
PS: 这题的问法也可能是 "受检异常和不受检异常的区别是什么"
答: 受检异常指的是在编译时接受编译器的检查, 如果没有处理异常则不能通过编译, Exception类及其子类都属于受检异常, RuntimeException类
常见的异常有哪些
受检: 接受编译器的检查
Error错误 | Exception编译时异常(受检) | RuntimeException运行时异常(不受检) |
内存溢出 OutOfMenoryError | 数据库异常 SQLException | 空指针异常 NullPointerException |
栈溢出 StackOverflowError | 类找不到异常 ClassNotFoundException | 类型转换异常 ClassCastException |
IO流异常 IOException | 算术异常 ArithmeticException | |
文件找不到异常 FileNotFoundException | 索引越界 IndexOutmatchException | |
输入不匹配异常 InputMismatchException | ||
数字转换异常 NullberDormatException |
Final 修饰符的作用
final表示- 最终的
修饰变量,称为常量,值不可以修改
修饰方法,称为最终方法,方法不可以被子类重写
修饰符,称为最终类,类不可以被继承
abstract关键字是否可以与final同时出现
或者这么问能不能同时用abstract和final修饰类或者方法
答案是不能,原因是:
- abstract修饰的类称为抽象类,抽象类不能被实例化,只能被继承,而final是阻止类被继承
- abstract修饰的方法称为抽象方法,抽象方法必须让子类重写,而final是阻止子类重写
final修饰的变量真的不能被改变吗
如果final修饰的变量是基本数据类型,指向常量池,那么值不可以修改
如果final修饰的变量是引用数据类型,指向堆,那么指针不可以修改,但是指针指向的对象内的成员可以修改