异常
异常是指程序运行时(非编译)所发生的非正常情况或错误,当程序违反了语言规则,jvm就会将出现的错误表示一个异常抛出。异常也是java 的对象,定义了基类 java.lang.throwable作为异常父类。 这些异常类又包括error和exception。两大类
error类异常主要是运行时逻辑错误导致,一个正确程序中是不应该出现error的。当出现error一般jvm会终止。
exception表示可恢复异常,包括检查异常和运行时异常。
检查异常是最常见异常比如IO异常、SQL异常,都发生在**编译阶段。**这类通过try…catch捕捉 。
而运行时异常,编译器没有强制对其进行捕捉和处理。一般都会把异常向上抛出,直到遇到处理代码位置,若没有处理块就会抛到最上层,多线程用thread的run()抛出,单线程用main()抛出。常见的运行异常包括、空指针异常、类型转换异常、数组越界异常、数组存储异常、缓冲区溢出异常、算术异常等。
题型一:try块中抛出异常,try、catch和finally中都有return语句
public static int WithException(){
int i=10;
try{
System.out.println("i in try block is : "+i);
i = i/0;
return --i;
}
catch(Exception e){
System.out.println("i in catch - form try block is : "+i);
--i;
System.out.println("i in catch block is : "+i);
return --i;
}
finally{
System.out.println("i in finally - from try or catch block is--"+i);
--i;
System.out.println("i in finally block is--"+i);
return --i;
}
}
执行顺序:
抛出异常后,执行catch块,在catch块的return的- -i执行完后,并不直接返回而是执行finally,因finally中有return语句,所以,执行,返回结果6。
i in try block is : 10
i in catch - form try block is : 10
i in catch block is : 9
i in finally - from try or catch block is--8
i in finally block is--7
6
结论:
try块中抛出异常,try、catch和finally中都有return语句,返回值是finally中的return。
题型二:如果try,finally语句里均有return,忽略try的return,而使用finally的return.
如果finally块中有return语句的话,它将覆盖掉函数中其他return语句。
结果30
题型三:
以下代码段执行后的输出结果为:
public class Test {
public static void main(String[] args) {
System.out.println(test());
}
private static int test() {
int temp = 1;
try {
System.out.println(temp);
return ++temp;
} catch (Exception e) {
System.out.println(temp);
return ++temp;
} finally {
++temp;
System.out.println(temp);
}
}
}
执行顺序为:
输出try里面的初始temp:1;
temp=2;
保存return里面temp的值:2;
执行finally的语句temp:3,输出temp:3;
返回try中的return语句,返回存在里面的temp的值:2;
输出temp:2。
小结:
如果try语句里有return,返回的是try语句块中变量值。
详细执行过程如下:
- 如果有返回值,就把返回值保存到局部变量中;
- 执行jsr指令跳到finally语句里执行;
- 执行完finally语句后,返回之前保存在局部变量表里的值。
题型四:
下列输出结果为:
package Test;
public class Test {
private static void test(int[] arr) {
for (int i = 0; i < arr.length; i++) {
try {
if (arr[i] % 2 == 0) {
throw new NullPointerException();
} else {
System.out.print(i);
}
} finally {
System.out.print("e");
}
}
}
public static void main(String[]args) {
try {
test(new int[] {0, 1, 2, 3, 4, 5});
} catch (Exception e) {
System.out.print("E");
}
}
}
eE
这道主要是要知道调用的方法报异常前要先执行完finally代码块,还有没有catch语句对异常做出处理,所以异常会往上抛至调用处,中断test()方法的继续执行。试对比:
package Test;
public class Test {
private static void test(int[] arr) {
for (int i = 0; i < arr.length; i++) {
try {
if (arr[i] % 2 == 0) {
throw new NullPointerException();
} else {
System.out.print(i);
}
} catch (NullPointerException e){
System.out.print("catch!");
}finally {
System.out.println("e");
}
}
}
public static void main(String[]args) {
try {
test(new int[] {0, 1, 2, 3, 4, 5});
} catch (Exception e) {
System.out.print("E");
}
}
}
输出:
catch!finally
1finally
catch!finally
3finally
catch!finally
5finally
因为有catch代码块对异常做出相应处理,所以异常不会往上抛,故main方法中的catch代码块没有执行,另外,test()方法也不会中断,提前退出。
题型五:
1.执行foo(0)时,不满足try语句块中的if语句,所以不会抛出异常,执行finally语句
2.执行foo(1)时,满足try中的If语句,抛出异常,在catch中进行异常处理,虽然有return语句,但是finally中的内容必须执行,也就是说要先执行了finally才进行return操作,return后 output += “4”将不会再执行.
3423
一些易忽视的点:
throw new Exception(" ");
Java异常都继承自类Throwable,Throwable子类有Error和Exception,其中Exception又分为运行时异常和编译时异常。编译时异常是未雨绸缪性质的异常,是防范,需要显示处理。运行时异常是程序员问题造成,并不强制进行显示处理。
总体结论:
结论一:
return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)
结论二:
finally里面不建议放return语句,根据需要,return语句可以放在try和catch里面和函数的最后。可行的做法有四:
(1)return语句只在函数最后出现一次。
(2)return语句仅在try和catch里面都出现。
(3)return语句仅在try和函数的最后都出现。
(4)return语句仅在catch和函数的最后都出现。
结论三:
catch可以省略,try的形式有三种:
try-catch
try-finally
try-catch-finally
但catch和finally语句不能同时省略!