java面试题之异常

在这里插入图片描述
在java中提供了一套异常处理机制,用来处理应用程序运行过程中出现的错误。
Throwable是异常机制中错误(Error)和异常(Exception)的根类,用来保存和描述异常信息(线程创建时线程执行堆栈的快照)。Throwable有两 个子类:Error(错误)和Exception(异常)。

Error和Exception的区别?

Error:通常由环境或者硬件出现问题造成的错误,应用无法处理和恢复这类错误。比如:系统崩溃,内存不足,堆栈溢出等等。
Exception:表示应用程序出现了问题,但还是可能处理和恢复的。比如:程序员可以捕获异常并处理掉异常。

运行时异常和编译时异常区别?

RuntimeException:运行时异常 表示程序在运行过程中可能出现的异常,但是java编译器不会检查这类异常。比如:NullPoniterException,ClassCastException等
编译时异常:java编译器会检查这类异常,必须处理(捕获异常或者抛出),否则编译不通过。
例如:程序员书写代码不规范,存在语法错误。
编译器检查到可能出现ClassNotFoundException,IOException等类型的异常。

异常处理中的关键字有那些?

异常处理中的关键字:try,catch,finally,throw,throws。
try:用来处理可能出现异常的代码。
catch:紧跟在try后面,如果try块中出现异常,则catch会捕获到该异常。
finally:无论前面是否发生异常,都会执行finally块中的代码(除非调用System.exit(0)),常用于资源的释放,流的关闭。
throw:用在方法内部,用来抛出一个指定的异常。
throws:用在方法签名的后面,用来抛出一系列的异常。

JVM是怎样处理异常的?

当一个方法中出现异常时,会创建一个异常对象,这个异常对象(异常名称、异常描述和异常发生时应用程序的状态等信息等)被抛给虚拟机JVM,JVM会顺着调用栈,去查找捕获该异常的代码。即查找看看有没有try-cath块来处理该异常,如果能找到,则在catch中处理异常,如果没有找到,则抛给JVM默认的异常处理器处理。

java处理异常的方式?

java处理异常的方式有两种:
1、通过try-catch块来捕获异常。
2、通过throws抛出异常,由程序调用者去处理异常。抛出的异常应该是原始异常类型或是其子类的异常类型。

throw和throws的区别?

throw:用在方法的内部,用来抛出一种异常,用来抛出方法或代码块中的异常。
throws:用在方法签名的后面,可以抛出多个异常。

try-catch-finally中,try中return了,finall还会执行吗?一定会被执行吗?

不管是try中return还是catch中return了,finally都会在return返回前执行。
如果finally之前调用了System.exit(0)或者应用程序异常退出则不会调用finally中的代码。

final、finally和finalize的区别?

final:可以修饰变量、方法、类,修饰变量表示该变量是一个常量不能够修改,修饰方法表示该方法不能够重写、修饰类表示该类不被继承。
finally:*一般和try-catch块一起使用,用在处理异常的时候,把一定要执行的代码放finally代码块中,无论是否发生异常,finally中的代码一定执行。常用与关闭资源。
finalize:*是Object类中的一个方法,用于垃圾回收器将对象从内清除之前做一些必要的工作。

ClassNotFoundException和NoClassDefFoundError的区别?

ClassNotFoundException:是受检查的异常,必须处理,需要通过try-catch代码块,来进行捕获和处理,或者在方法名后声明throws抛出该异常。当使用Class.forName,ClassLoader.loadClass动态加载类到内存的时候,传入的类路径中找不到该类,会抛出该异常。
**NoClassDefFoundError:**是Error类型的错误,是由JVM引起的,不应该尝试捕获这个错误。JVM或着ClassLoader尝试加载某个类时,内存中找不到该类的定义,意思是编译时该类还存在,但是运行时找不到了,可能是编译后被删除了。

常见的异常有哪些?

NullPointerException:空指针异常(RuntimeException)
ArithmeticException:算术异常(RuntimeException)
ClassCastException:类型转换异常(RuntimeException)
IndexOutOfBoundsException:索引越界异常(RuntimeException)
ArrayIndexOutOfBoundsException:数组下标越界异常(RuntimeException)
NumberFormatException:数字格式转换异常(RuntimeException)
ClassNotFoundException:找不到类异常
IOException:IO异常
OutOfMemoryError:内存不足错误
StackeOverflowError:堆栈溢出错误

如何自定义异常

1、继承Exception或着RuntimeException
继承Exception类需要调用者自己处理异常,如果调用者不需要处理异常可以继承RuntimeException。
2、重写构造方法

//此处用继承Exception举例,如果调用者不想处理异常,则可以继承RuntimeException,构造方法可以根据需要实现其中的部分或者全部
public class MyException extends Exception{
	public MyException (){	//构造方法1
 	}
	public MyException (String message){ //构造方法2
            super(message);
 	}
 	public MyException (String message,Throwable cause){ //构造方法3
            super(message,cause);
 	}
 	public MyException (Throwable cause){ //构造方法4
            super(cause);
 	}
}
异常处理的最佳实践

1、异常不要用来做流程控制,条件控制。说明:异常设计的初衷是解决程序运行中各种意外的情况,且异常的处理效率比条件判断方式低很多。

2、不要捕获运行时异常(RuntimeException)

3、catch时分清稳定代码和非稳定的代码,稳定代码是指无论如何不会出错的代码。对于非稳定的代码catch应区分异常类型。说明:对大段代码进行try-catch,是程序无法根据不同的异常做出正确异常处理,也不利于问题定位。

4、不要生吞异常。说明:捕获异常是为了处理它,不要捕获了却什么都不处理直接抛弃掉,如果不想处理它,可以将该异常抛给它的调用着。反例:

public void doNotIgnoreExceptions() {
    try {
        // do something
    } catch (NumberFormatException e) {
        //什么事情都不做,直接抛弃异常
    }
}

5、finally块中必须对资源对象、流对象进行关闭,有异常也要try-carch。jdk7及以上可以使用try-with-resources

public void closeResource() {
    FileInputStream inputStream = null;
    try {
        File file = new File("./tmp.txt");
        inputStream = new FileInputStream(file);
        // use the inputStream to read a file
    } catch (FileNotFoundException e) {
        log.error(e);
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                log.error(e);
            }
        }
    }
}
或者
public void closeResource() {
    File file = new File("./tmp.txt");
    try (FileInputStream inputStream = new FileInputStream(file);) {
        // use the inputStream to read a file
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}

6、不要再finally块中使用return。说明:try块中的return语句执行成功后,并不是马上返回,而是继续执行finally块中的语句,如果此处存在return,则直接返回,无情丢掉了try块中的返回点。反例:

private int x = 0;
public int checkReturn() {
    try {
        // x`在这里插入代码片`等于1,此处不返回
        return ++x;
    } finally {
        // 返回的结果是2
        return ++x;
    }
}

7、捕获异常和抛出异常,必须是完全匹配的,或者捕获异常是抛出异常的父类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值