该文章参考:《Java核心技术卷一 ——基础知识》
1. 异常分类
由此图可以看出,所有的异常种类都由Throwable 继承而来,然后再分为具体两种,Error和Exception。
Error类异常
这一类异常属于java虚拟机异常,一般不应该由程序员手动抛出,出现这种异常一般只能通知用户,尽力的安全停止程序。
Exception类异常
这一类异常又分为两个分支IOException和RuntimeException。当程序发生RuntimeException的时候,毫无疑问是你的程序写错了,才会导致这样的结果,这个时候就需要检查代码。当发生IOException的时候,程序可能不是并没有错误,例如读取文件不存在等等。
常见派生于 RuntimeException 的异常
- IndexOutOfBoundsException(数组越界异常)
- NullPointerException(空指针异常)
- ClassCastException(类型转换异常)
- ClassNotFoundException (类没有发现异常)
2.声明异常
声明异常,我们书写方法的时候不但要告诉编译器我们返回的是什么,还要告诉编译器,这一段程序可能发生什么异常。使用throws关键字在方法名上声明。
例子1:使用throws关键字声明异常
public void defineThrow() throws ClassCastException {
*******
}
例子2:如果要声明多个异常,使用逗号隔开
public void defineThrow() throws ClassCastException ,NullPointerException{
*******
}
3.抛出异常
抛出异常,我们使用throw 关键字,throws和throw的区别就是throws使用在方法名上,throw使用在方法体中,throw 通 常和try catch语句连用
例子:
public void defineThrow() {
try {
}catch (Exception e){
throw e;
}
}
4.捕获异常
因为我们的程序发生了异常后面的代码就中止执行了,这时如果我们需要进一步的操作就需要捕获异常, 捕获异常使用的是try catch 代码块,当try代码块里面发生异常,立即跳转到catch中代码块中执行
例子1:我们首先测试一下程序不发生异常时,try catch 执行流程
public class DemoTest {
public void testTryCatch() {
int i = 0;
try {
i = 1;
System.out.print("执行try代码块内容i=" + i);
} catch (Exception e) {
i = 2;
System.out.print("执行catch代码块内容i=" + i);
}
}
public static void main(String arg[]) {
DemoTest demoTest = new DemoTest();
demoTest.testTryCatch();
}
}
执行结果为:
例子2:程序发生异常时,try catch 执行流程
public class DemoTest {
public void testTryCatch() {
int i = 0;
try {
i = 1;
System.out.println("执行try代码块内容i=" + i);
throw new Exception();
} catch (Exception e) {
i = 2;
System.out.println("执行catch代码块内容i=" + i);
}
}
public static void main(String arg[]) {
DemoTest demoTest = new DemoTest();
demoTest.testTryCatch();
}
}
结果:
结论:catch中代码块只有在发生对应异常的时候才执行。
例子3:如何在catch中捕获多个异常
public void catchMoreException(){
try{
}catch (ClassCastException |NullPointerException e){
*****
}
}
5.finally关键字的用法
当代码抛出一个异常时, 就会终止方法中剩余代码的处理,并退出这个方法的执行。如 果方法获得了一些本地资源,并且只有这个方法自己知道,又如果这些资源在退出方法之前 必须被回收,那么就会产生资源回收问题。有两种方法,一是捕获所有异常并且抛出。另外一个就是使用finally代码块。
public void finallyWord() throws IOException{
InputStream in=new FileInputStream("1");
try {
//执行操作
} finally {
//关闭输入输出
in.close();
}
注:由这里看出try不一定和catch一起使用
下面我另外说明一下try catch finally 最最常见的面试题
写出下面代码的返回结果
public class demo {
public String interviewProblem(String val) {
try {
//这里这样写是因为想造成空指针异常
int i = val.length();
return "try";
} catch (Exception e) {
return "catch";
} finally {
return "finally";
}
}
public static void main(String arg[]) {
demo demo = new demo();
System.out.println(demo.interviewProblem(null));
}
}
博主第一次做的时候,答案是catch返回的值。这里要记住了,无论前面执行的代码产生异常或者方法已经返回,finally的代码块必须是要执行的。
5.带资源的try语句
这是java1.7之后引入的新特性,暂时在开发中很少见,这个新特性出现后我们不需要在finally再进行资源的关闭,不论这个块如何退出, in 和 out 都会关闭。如果你用常规方式手动编程,就需要两个嵌 套的 try/finally语句。
public void tryHaveResource(String val) throws FileNotFoundException {
try (Scanner in = new Scanner(new FileInputStream(val), "utf-8")) {
while (in.hasNext()) {
System.out.println(in.next().toUpperCase());
}
}
}