什么是网站建设技术,网站建设都需要那些材料,深圳响应式网页设计,宁波网站推广方式怎么样首先看一下java中异常相关类的继承关系#xff1a; 引用 1、分类
异常可以分为受查异常和非受查异常#xff0c;Error和RuntimeException及其所有的子类都是非受查异常#xff0c;其他的是受查异常。 两者的区别主要在#xff1a;
受检的异常是由编译器#xff08;编译…首先看一下java中异常相关类的继承关系 引用 1、分类
异常可以分为受查异常和非受查异常Error和RuntimeException及其所有的子类都是非受查异常其他的是受查异常。 两者的区别主要在
受检的异常是由编译器编译阶段强制执行的必须try-catch捕获或者往上抛出用于指示不受程序控制的异常情况例如I/O 错误。而非受检的异常在运行时发生用于指示编程错误例如空指针。正因为如此受检异常在使用的时候需要比非受检异常更多的代码来避免编译错误。
常见的异常有 之所以要定义受检异常和非受检异常主要是因为两者有着不同的作用 在程序中存在一些需要用户在编译期间就去检查的问题比如FileNotFoundException、IOException这些异常涉及资源处理调用者需要捕获其实它可以提醒开发者如果被调用的方法出现这类异常时程序应该做好预判并处理比如IOExcetion我们需要对流进行关闭操作。 而非受检发生在运行期间是程序运行过程中可能发生的错误类型比如NullpointExcetpion这些异常我们可以捕获也可以不捕获。但是捕获这些异常只能打印一些日志除此之外什么都做不了。捕获了也无法在程序中解决
2、finally与return
2.1 finally原理
public class Demo3_11_4 {public static void main(String[] args) {int i 0;try {i 10;} catch (Exception e) {i 20;//异常表中有3行分别是监测try中出现的异常、catch中出现的异常catch中处理异常时也是可能产生异常的} finally {i 30;}System.out.println(i);}
}
//输出30字节码 可以看到在字节码中 finally 中的代码被复制了 3 份分别放入 try 流程catch 流程以及 catch 剩余的异常类型流程。当catch中代码出现异常时该异常对象会被抛出。
2.2 finally 对返回值影响
finally中return
public class Demo3_12_2 {public static void main(String[] args) {int result test();System.out.println(result);}public static int test() {try {return 10;} finally {return 20;}}
}
//输出 20字节码
//字节码指令
public static int test();descriptor: ()Iflags: ACC_PUBLIC, ACC_STATICCode:stack1, locals2, args_size00: bipush 10 // - 10 放入栈顶2: istore_0 // 10 - slot 0 (从栈顶移除了后面还有字节码不能return)3: bipush 20 // - 20 放入栈顶5: ireturn // 返回栈顶 int(20)6: astore_1 // catch any - slot 17: bipush 20 // - 20 放入栈顶9: ireturn // 返回栈顶 int(20)Exception table:from to target type0 3 6 anyLineNumberTable: ...StackMapTable: ...由于 finally 中的 ireturn 被插入了所有可能的流程因此返回结果肯定以 finally 的为准
try中returnfinally中修改return值
public class Demo3_12_2 {public static void main(String[] args) {int result test();System.out.println(result);}public static int test() {int i 10;try {return i;} finally {i 20;}}
}//输出10字节码 可以看到在try中执行return时已经暂存的i10后续修改i不会改变本地变量表中的i。
2.3 finally中return对异常的影响
在2.1中我们可以看到为了防止catch捕获异常处理的过程中产生异常后直接抛出而不执行finally中的代码因此在字节码中对try中代码也进行了异常的跟踪并最后抛了出去。
有如下代码
public class Demo3_12_2 {public static void main(String[] args) {int result test();System.out.println(result);}public static int test() {int i 10;try {i 1/0;return i;} finally {i 20;//return i;}}
}
//输出30问题1会抛出异常吗
public static int test();descriptor: ()Iflags: ACC_PUBLIC, ACC_STATICCode:stack2, locals3, args_size00: bipush 102: istore_03: iconst_14: iconst_05: idiv6: istore_07: iload_08: istore_19: bipush 20 -----------11: istore_012: iload_113: ireturn -----------14: astore_215: bipush 20 -----------17: istore_018: aload_219: athrowException table:from to target type3 9 14 any从字节码中可以看到当前代码在try中——字节码3到9不包括9出现异常会直接跳到14将异常对象放到slot2然后执行finally代码将20-i抛出异常对象。所以时可以抛出异常的。
问题2finally中添加return后会抛出异常吗 public static int test();descriptor: ()Iflags: ACC_PUBLIC, ACC_STATICCode:stack2, locals3, args_size00: bipush 102: istore_03: iconst_14: iconst_05: idiv6: istore_07: iload_08: istore_19: bipush 2011: istore_012: iload_013: ireturn14: astore_215: bipush 2017: istore_018: iload_019: ireturnException table:from to target type3 9 14 any可以看到代码finally中添加return后字节码中 athrow 指令没了这就表明不会抛出异常了即finally中的return会吞掉异常对象所以不要在finally中return。
小结finally吞掉异常的原因是要保证finally中代码必须执行然后才抛出异常但是如果finally中有return的话执行到finally中的return方法就结束了没有机会去跑异常了。