文章目录
Q1:说一下Java中的异常体系?
异常,这些类以 Throwable 为顶层父类。
Throwable 又派生出 Error 类和 Exception 类。
错误:Error 类以及他的子类的实例,代表了 JVM 本身的错误。错误不能被程序员通过代码处理,Error 很少出现。因此,程序员应该关注 Exception 为父类的分支下的各种异常类。
异常:Exception 以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被 Java 异常处理机制使用,是异常处理的核心。
编译时异常必须显示处理,运行时异常交给虚拟机。
运行时异常可以不处理。当出现这样的异常时,总是由虚拟机接管。比如我们从来没有人去处理过 Null Pointer Exception 异常,它就是运行时异常,并且这种异常还是最常见的异常之一。出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由 Thread.run () 抛出,如果是单线程就被 main () 抛出(此时main方法需要在方法签名中throws异常的种类)。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,整个程序也就退出了。运行时异常是 Exception 的子类,也有一般异常的特点,是可以被 Catch 块处理的。只不过往往不对它处理罢了。也就是说,如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
Q2:运行时异常和一般异常的区别?
异常:表示程序运行过程中可能出现的非正常状态。
运行时异常:表示虚拟机的通常操作中可能遇到的异常,是一种常见的运行错误。---------Java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出被捕获的运行时异常。
Q2:Error和Exception的区别?
错误:Error 类以及他的子类的实例,代表了 JVM 本身的错误。错误不能被程序员通过代码处理,Error 很少出现。因此,程序员应该关注 Exception 为父类的分支下的各种异常类。
异常:Exception 以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被 Java 异常处理机制使用,是异常处理的核心。
Q3:写出你最常见的5个RuntimeException?
- java.lang.
NullPointerException
(空指针异常):调用了未经初始化的对象或者是不存在的对象。 - java.lang.
ClassNotFoundException
(指定的类找不到):类的名称和路径加载错误;通常都是程序试图通过字符串来加载某个类时可能引发的异常。 - java.lang.
NumberFormatException
(数字格式异常):字符型数据中包含非数字型字符。 - java.lang.
IndexOutOfBoundsException
(数组下标越界异常):常见于操作数组对象时发生。 - java.lang.
IllegalArgumentException
:方法传递参数错误。 - java.lang.
ClassCastException
:数据类型转换异常。
IllegalArgumentException不合法的参数异常
一个简单的小例子:
package Test2;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test3 {
public static void main(String[] args) {
Date day = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = df.format(day);
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM");
String format = dateFormat.format(date);
System.out.println(format);
}
}
运行会报错:
无法将给定的对象作为日期格式化,即因为传递了一个错误的参数。
Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given Object as a Date
at java.text.DateFormat.format(DateFormat.java:281)
at java.text.Format.format(Format.java:140)
at Test2.Test3.main(Test3.java:14)
Q4:如何处理异常?
(1)异常处理的两种方式
- 自己处理
- 向上抛,交给调用者处理。
(2)具体的处理方式的选择原则
- 自己明确的知道如何处理,就要处理掉。
- 不知道如何处理,就交给调用者处理。
注:异常, 不能捕获了之后什么也不做。或者只是使⽤e.printStacktrac
Q5:try()里面有⼀个return语句, 那么后面的finally{}里面的代码会不会被执行?什么时候执行,return前还是return后?
- 如果try中有return语句,那么finally中的代码还是会执行的。
- 因为return表示的是要整个方法体返回,所以,finally中的语句会在try中return之前执行。
- 但是return前执行的finally快内,对数据的修改效果对于引用类型和值类型会有所不同。
// 测试 修改值类型
static int f(){
int ret = 0;
try {
return ret; // 返回 0,finally内的修改效果不起作用
}finally {
++ret;
System.out.println("finally");
}
}
// 测试 修改引用类型
static int[] f2(){
int [] ret = new int[]{0};
try {
return ret; // 返回 [1],finally内的修改效果起了作用
}finally {
ret[0]++;
System.out.println("finally执行了···");
}
}
Q6:调用下面方法会返回什么值?
异常机制:
有这么一个原则,如果在catch中遇到return或者异常等能使函数终止的事件,那么有finally就必须先执行完finally代码块里边的代码然后再返回catch/try中的返回值
分析:
代码走到第3行的时候会遇到一个MathException,这时第四行的代码就不会执行了,代码直接跳转到catch语句中,走到第6行的时候(异常机制),因此代码又跳到第8行,可惜第8行是一个return语句,那么这个时候方法就结束了,因此第6行的返回结果就无法被真正返回。(如果finally仅仅是处理了一个释放资源的操作,那么该道题最终返回的结果就是2。)因此上面返回值是3
1 public int getNum(){
2 try {
3 int i=1/0;
4 return 1;
5 }catch (Exception e){
6 return 2;
7 }finally {
8 return 3;
9 }
10 }
Q7:throw和throws的区别?
1、throws出现在方法函数头;而throw出现在函数体。
2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。
3、两者处理异常的方式,均是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
Q8:java 中 finally 块一定会执行吗?
答:不一定,分情况。
- 因为首先想要执行 finally 块的前提是必须执行到了 try 块,当在 try 块或者 catch 块中有 System.exit(0); 这样的语句存在时 finally 块就不会被执行到了,因为程序被结束了。
- 此外当在 try 块或者 catch 块里 return 时 finally 会被执行;而且 finally 块里 return 语句会把 try 块或者 catch 块里的 return 语句效果给覆盖掉且吞掉了异常。
static void f3(){
try {
int i=10/0;
System.out.println("try");
}
catch (Exception e){
System.out.println("catch");
System.exit(1);
}
finally {
System.out.println("finally");
}
}
Q9:谈谈final、finally、finalize区别?
final
用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖、类不可继承。finally
是异常处理语句结构的一部分,表示总是执行。finalize
是 Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用。当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。finalize()方法会在对象被回收前调用。
Q10:建议finally
不要在 fianlly 中使用 return。
不要在 finally 中抛出异常。
减轻 finally 的任务,不要在 finally 中做一些其它的事情,finally 块仅仅用来释放资源是最合适的。
将尽量将所有的 return 写在函数的最后面,而不是 try … catch … finally 中。
Q11:throw 终结式异常处理模式
public static void main(String[] args) {
try {
abc();
} catch (Exception e) {
System.out.println("int the catch first");
e.printStackTrace();
System.out.println("in the catch last");
}
System.out.println("the last");
}
public static void abc() throws Exception {
System.out.println("1");
if (true) {
throw new Exception("异常");
}
System.out.println("2");
}
1
int the catch first
java.lang.Exception: 异常
at Try.abc(Try.java:18)
at Try.main(Try.java:4)
in the catch last
the last