Android面试系列文章2018之Java部分异常篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ClAndEllen/article/details/79389561

Android面试系列文章2018之Java部分异常篇

1.异常体系

[1]Error:java中所有错误的基类。错误通常是我们无法处理的,绝大多数情况下,我们不应该试图捕获错误。比如:OOM。

[2]非运行时的异常:是在编译期间发生的异常,这是编译期间必须检测的,不管检测和不检测出异常,你必须尝试去捕捉这些非运行时异常,然后编写相应的异常解决措施代码。

   非运行异常包括很多子类,比如IOException,SQLExceptio等,这些可能发生的异常在编写代码时必须要对其进行捕捉和编写解决措施,
   比如下面的语句必须进行捕捉,使用以下代码格式捕捉:

   try{
      (可能产生非运行时异常的代码块)
   }catch(AException e){
      (编写解决这个A非运行时异常的解决措施的代码块)
   }catch(BException e){
      (编写解决这个B非运行时异常的解决措施的代码块)
   }catch(CException e){
      (编写解决这个C非运行时异常的解决措施的代码块)
   }catch(...Exception e){
      (编写解决这个...非运行时异常的解决措施的代码块)
   }
   finally{
      (此处最好用来释放一些占用的资源)
   }

[3]运行时异常RunntimeException
   顾名思义就是程序运行时所产生的异常,运行时异常也可以通过try{}catch{}finally{}语句捕捉和处理,也可以不去捕捉和处理。

   try{
      (可能产生运行时异常的代码块)
   }catch(AException e){
      (编写解决这个A运行时异常的解决措施的代码块)
   }catch(BException e){
      (编写解决这个B运行时异常的解决措施的代码块)
   }catch(CException e){
      (编写解决这个C运行时异常的解决措施的代码块)
   }catch(...Exception e){
      (编写解决这个...运行时异常的解决措施的代码块)
   }
   finally{
      (此处最好用来释放一些占用的资源)
   }

   来看看常见的运行时异常的类型吧,比如:
   a.空指针异常(最长见的一种)
     int[]  num = null;
     syso("num[5]"+num[5]);

     解释:由于num中在内存中是空的,当调用num[5]的时候发现栈内存的num没有任何指针指向堆内存中,此时结束程序的运行
           所以就会报空指针异常,输出一下异常提示:
           Exception in thread "main" java.lang.NullPointerException
           at MyExceptionSystem.NoPlaneException.main(NoPlaneException.java:18)

   b.数组越界异常
     int[] num = new int[]{1,2,3,4};
     syso("num[5]="+num[4]);

     解释:通过new关键字在堆内存中创建了int[]对象(连续的堆内存空间),其长度为4,当你代码中访问第5个元素的时候,发现并没有第5个元素,
           此时结束程序的运行,然后报数组越界异常,输出以下异常提示:
           Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
           at MyExceptionSystem.NoPlaneException.main(NoPlaneException.java:18)

   c.其他的等等
     运行时异常不只是包括空指针异常和数组越界异常两种,还包括很多......

2.异常的使用

2.1 运用Java异常处理机制

1.try…catch语句

2.finally语句:任何情况下都必须执行的代码

3.throws子句:声明可能发生的异常类

4.throw:抛出具体的异常对象。

2.2 异常处理的原理

1.Java虚拟机用方法调用栈(method invocation stack)来跟踪每个线程中一系列的方法调用过程。

2.如果在执行方法过程中抛出异常,则Java虚拟机必须找到能捕获该异常的catch代码块。

3.当Java虚拟机追溯到调用栈的底部的方法的时候,如果仍然没有找到处理该异常的代码块,这样它就会按步骤处理,首先会打印方法调用栈的异常信息,然后如果所处的线程不是主线程,那么就会终止这个线程。

2.3 异常流程的运行过程

1.finally语句不被执行的唯一情况就是先执行了用于终止程序的System.exit()语句。

2.return语句用于退出本方法。

3.如果return语句在try语句或者catch语句中,那么finally代码块在return语句之前被执行。

4.建议在finally代码块中不要使用returne语句。

3.异常的面试题

3.1 Java中检查异常和非检查异常的区别?

  检查型异常(CheckedException)
在Java中所有不是RuntimeException派生的Exception都是检查型异常。当函数中存在抛出检查型异常的操作时该函数的函数声明中必须包含throws语句。调用改函数的函数也必须对该异常进行处理,如不进行处理则必须在调用函数上声明throws语句。

  检查型异常是JAVA首创的,在编译期对异常的处理有强制性的要求。在JDK代码中大量的异常属于检查型异常,包括IOException,SQLException等等。

  非检查型异常(UncheckedException)
在Java中所有RuntimeException的派生类都是非检查型异常,与检查型异常对比,非检查型异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理。
常见的NullPointException,ClassCastException是常见的非检查型异常。非检查型异常可以不使用try…catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。对于RuntimeException的子类最好也使用异常处理机制。虽然RuntimeException的异常可以不使用try…catch进行处理,但是如果一旦发生异常,则肯定会导致程序中断执行,所以,为了保证程序再出错后依然可以执行,在开发代码时最好使用try…catch的异常处理机制进行处理。

3.2 throw与throws的区别?

throws
    用在方法声明后面,跟的是异常类名
    可以跟多个异常类名,用逗号隔开
    表示抛出异常,由该方法的调用者来处理
    throws表示出现异常的一种可能性,并不一定会发生这些异常

throw
    用在方法体内,跟的是异常对象名
    只能抛出一个异常对象名
    表示抛出异常,由方法体内的语句处理
    throw则是抛出了异常,执行throw则一定抛出了某种异常

3.3 如果finally代码块之前方法返回了结果,或者JVM退出了,finally代码块中的代码还会执行吗?

  如果finally代码块之前方法返回了结果,finally代码块依然会执行,并且会在return语句之前执行。如果finally代码块之前JVM退出了finally代码块中的代码不会执行。

3.4 Java中final,finally和finalize关键字的区别

  final:最终的意思,可以修饰类,成员变量,成员方法
修饰类,类不能被继承
修饰变量,变量是常量且只能被赋值一次
修饰方法,方法不能被重写

  finally:是异常处理的一部分,用于释放资源。
一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了。

  finalize:是Object类的一个方法,用于垃圾回收,在对象被回收时调用,比如:A类生产的对象a被回收了,就会去执行A类的finalize()方法。

3.5 什么情况下finally语句代码块不会被执行?

  1.在try代码块之外返回结果。

  2.在将要执行finally代码块之前JVM退出了。

  3.在将要执行finally代码块的时候,所处的线程突然结束了。

没有更多推荐了,返回首页