一、基本知识点
1.什么是异常
在程序运行的过程中意外发生的情况,背离我们程序本身的意图的表现,都可以理解为异常。
2.异常的起源与分类
所有的异常类是从 java.lang.Exception 类继承的子类。 Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
3.异常处理机制
通过5个关键字来实现:try,catch,finally,throws,throw
try -catch -finally
正常情况:
当程序没有发生异常的时候,不执行catch内内容,直接执行后面的相关代码。
异常出现:
catch中异常无法被匹配时,程序中断执行 多重捕获块 一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
多重捕获块的语法如下所示:
try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 } 复制代码
注意:
-
可以使用多个catch块。
-
如果有return关键字,一定是在执行完finally语句后再执行return 返回退出
-
处理异常时,采用逻辑去合理规避的同事辅助try-catch处理
-
在多重catch块后,可以加一个catch(Exception e)来处理可能会别遗漏的异常
-
对于不确定的代码,可以加上try-catch,处理潜在的异常。
-
尽量去处理异常,切忌只是简单的调用 print.StackTrace() 打印
-
具体如何处理异常,要根据不同的业务需求和异常类型去决定。
-
尽量添加finally语句块,去释放占用的资源(例如。关闭文件、关闭数据库的链接)
throw&throws
通过throws声明将要抛出何种类型的异常,通过throw将产生的异常抛出。 如果一个方法可能会出现异常,但没有能力处理,可以在方法声明处用throws子句声明抛出异常。
throw 抛出的异常有两种方式来处理:
-
自己抛出,自己解决
-
谁调用,谁解决
注意:当子类重写父类抛出异常的方法时,声明的异常必须是父类方法所声明异常的同类或者子类。
自定义异常
描述特定业务的异常类型。自定义一个类,继承Throwable类或者它的子类。
注意:
-
所有异常都必须是 Throwable 的子类。
-
如果希望写一个检查性异常类,则需要继承 Exception 类。
-
如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
异常链
如果我们在程序中,捕获一个异常的同时再抛出一个异常。如果希望将异常产生的原因一个传一个串起来,即底层的异常信息抛给上层,就形成了异常链。
二、面试问题:
(转自csdn blog.csdn.net/qq_37875585… )
1. 什么是Java中的异常?
-
异常是指程序在运行过程中发生的一些不正常事件。(如:除0溢出,数组下标越界,所读取的文件不存在)
2. Java中的异常处理关键字是什么?
-
throw:有时我们明确要创建异常对象然后抛出它来停止程序的正常处理。throw关键字用于向运行时抛出异常来处理它。
-
throws:当我们在方法中抛出任何已检查的异常而不处理它时,我们需要在方法签名中使用throws关键字让调用者程序知道该方法可能抛出的异常。调用方法可以处理这些异常或使用throws关键字将其传播给它的调用方法。我们可以在throws子句中提供多个异常,也可以与main()方法一起使用。
-
try-catch:我们在代码中使用try-catch块进行异常处理。try是块的开始,catch是在try块的末尾处理异常。我们可以使用try有多个catch块,try-catch块也可以嵌套。catch块需要一个应该是Exception类型的参数。
-
finally:finally块是可选的,只能用于try-catch块。由于异常会暂停执行过程,因此我们可能会打开一些不会关闭的资源,因此我们可以使用finally块。finally块总是被执行,无论是否发生异常。
3.Java中的检查型异常和非检查型异常有什么区别?
-
检查型异常和非检查型异常的主要区别在于其处理方式。
-
检查型异常都需要使用try,catch 和finally 关键字在编译器进行处理,否则会出现编译器报错。
-
对于非检查型异常则不需要这样做。Java中所有继承 Exception 的类的异常都是检查型异常,所有继承RuntimeException 的异常都被称为 非检查型异常。
4. error和exception有什么区别?
-
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
-
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
5. final, finally, finalize的区别?
-
final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。
-
finally是异常处理语句结构的一部分,表示总是执行。
-
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等(在垃圾回收的时候会调用被回收对象的此方法)
6. Java 中什么是异常链?
-
异常链是指在进行一个异常处理时抛出了另外一个异常,由此产生了一个异常链条,大多用于将受检查异常(checked exception)封装成为非受检查异常(unchecked exception)或者 RuntimeException。特别注意如果你因为一个异常而决定抛出另一个新的异常时一定要包含原有的异常,这样处理程序才可以通过 getCause() 和 initCause() 方法来访问异常最终的根源
7. try-catch-finally-return执行顺序?
-
不管是否有异常产生,finally块中代码都会执行。
-
当try和catch中有return语句时,finally块仍然会执行。 finally是在return后面的表达式运算执行的,所以函数返回值在finally执行前确定的,无论finally中的代码怎么样,返回的值都不会改变,仍然是之前return语句中保存的值。 finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
8. 列出常见的几种RunException?
-
NullPointerException - 空指针引用异常
-
ClassCastException - 类型强制转换异常
-
ArithmeticException - 算术运算异常
-
IndexOutOfBoundsException - 下标越界异常
-
NumberFormatException - 数字格式异常
-
EOFException - 文件已结束异常
-
FileNotFoundException - 文件未找到异常
-
SQLException - 操作数据库异常
9. Java异常类的重要方法是什么?
-
异常及其所有子类不提供任何特定方法,并且所有方法都在基类Throwable中定义。
-
String getMessage():此方法返回消息String of Throwable,并且可以在通过构造函数创建异常时提供消息。
-
String getLocalizedMessage():提供此方法,以便子类可以覆盖它以向调用程序提供特定于语言环境的消息。此方法getMessage()的可抛出类实现只是使用方法来返回异常消息。
-
synchronized Throwable getCause() :此方法返回异常的原因或null id,原因未知。
-
String toString():此方法以String格式返回有关Throwable的信息,返回的String包含Throwable类和本地化消息的名称。
-
void printStackTrace() :此方法将堆栈跟踪信息打印到标准错误流,此方法已重载,我们可以将PrintStream或PrintWriter作为参数传递,以将堆栈跟踪信息写入文件或流。