1.Java中的检查型异常(checked exception)和非检查型异常(RuntimeException)有什么区别?
检查型异常(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的异常处理机制进行处理。
2.Java异常处理中有哪些关键字?
Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果系统会抛出(throw)一个异常对象,可以通过它的类型来捕获(catch)它,或通过总是执行代码块(finally)来处理;
try用来指定一块预防所有异常的程序。
catch子句紧跟在try块后面,用来指定你想要捕获的异常的类型;
throw语句用来明确地抛出一个异常;
throws用来声明一个方法可能抛出的各种异常;
finally为确保一段代码不管发生什么异常状况都要被执行。
3.throw 和 throws这两个关键字在java中有什么不同?
throw语句用来明确地抛出一个异常;throws用来声明一个方法可能抛出的各种异常;
throw代表动作,表示抛出一个异常的动作;throws代表一种状态,代表方法可能有异常抛出
throw用在方法实现中;throws用在方法声明中;
throw只能用于抛出一种异常;throws可以抛出多个异常
4.什么是“异常链”?
异常链是一种面向对象编程技术,指将捕获的异常包装进一个新的异常中并重新抛出的异常处理方式。原异常被保存为新异常的一个属性(比如cause)。这个想法是指一个方法应该抛出定义在相同的抽象层次上的异常,但不会丢弃更低层次的信息。----百度百科
在java的构造方法中提供了异常链.. 也就是我们可以通过构造方法不断的将异常串联成一个异常链...
之所以需要异常链,是因为处于代码的可理解性,以及阅读和程序的可维护性...
我们知道我们每抛出一个异常都需要进行try catch ...那么岂不是代码很臃肿...
我们如果可以将异常串联成一个异常链,然后我们只捕获我们的包装异常,我们知道 RuntimeException 以及其派生类可以不进行try catch 而被jvm自动捕获并处理..
当然了我们可以自己定义自己的异常类从RuntimeException中派生,然后通过一级一级的包装,假如异常出现了JVM通过我们的自定义RuntimeException直接输出 cause(原因)也就是我们的异常链..因此我们的所有异常也就输出了,这样就减少了很多的异常处理的代码。。。
只有 Throwable ----> Exception RuntimeException Error提供了构造方法实现异常链的机制。。。其他异常需要通过initCause来
5.如果执行finally代码块之前方法返回了结果,或者JVM退出了,finally块中的代码还会执行吗?
不会,只有在try里面是有System.exit(0)来退出JVM的情况下finally块中的代码才不会执行。否则finally块中的代码都会执行。
思路:了解try.cath.finally的执行顺序就会迎刃而解,首先会执行try里面的代码,执行完了会查找有没有finally,如果没有,直接执行return或者是throw,如果有finally,先执行finally里面的代码,再执行try里面的 return或者是throw;一般来讲finally里面不会写return或者是throw,如果写了,会覆盖掉try里面的return和throw。
6.Java中final,finalize,finally关键字的区别?(北京面试题)
final
当这个关键字修饰一个类时,意味着他不能派生出新的子类,也就是说不能被继承,因此一个类不能被同时声明为abstract和final。当final修饰变量或者方法时,可以保证他们在使用中不会被改变。被声明为final的变量必须在初始化时给定初值,以后在使用时只能被引用而不能被修改。同样,当final修饰一个方法时,这个方法不能被重载。
finally
异常处理时提供finally来执行任何清楚操作。如果抛出一个异常,那么相匹配的catch子句就会被执行,然后控制就会转入finally块。
finalize
方法名。finalize方法在垃圾回收器执行内存对象清理时会调用finalize()方法进行前期的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
Java中所有类都从Object类中继承finalize()方法。
当垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的finalize()方法。值得C++程序员注意的是,finalize()方法并不能等同与析构函数。Java中是没有析构函数的。C++的析构函数是在对象消亡时运行的。由于C++没有垃圾回收,对象空间手动回收,所以一旦对象用不到时,程序员就应当把它delete()掉。所以析构函数中经常做一些文件保存之类的收尾工作。但是在Java中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行,显然指望它做收尾工作是靠不住的。那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。
7.try{}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?(北京面试题)
写一个小demo可以看出来:
8.error和exception有什么区别?
Error类和Exception类的父类都是throwable类,他们的区别是:
Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。
Exception类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
Exception类又分为运行时异常(Runtime Exception)和受检查的异常(Checked Exception ),运行时异常;ArithmaticException,IllegalArgumentException,编译能通过,但是一运行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。而受检查的异常,要么用try。。。catch捕获,要么用throws字句声明抛出,交给它的父类处理,否则编译不会通过。
5种常见异常:
ClassCastException(类转换异常)
IndexOutOfBoundsException(数组越界)
NullPointerException(空指针)
ArrayStoreException(数据存储异常,操作数组时类型不一致)
还有IO操作的BufferOverflowException异常
异常的层级: