欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java面试笔记之异常处理

程序员文章站 2022-03-06 18:04:10
...

针对Java面试题中的异常处理部分,特别地写一篇博文来总结一下。不说废话,先提出问题,再给出解决方案,再总结。走起!

1. 面试问题

基础知识:

Q1:什么是异常?什么是错误?异常和错误的区别是什么?

Q2:Java中的异常类的继承结构

Q3:异常中的运行异常和检查异常

Q4:try-catch-finally块的使用

Q5:自定义异常类的使用

Q6: throw和throws的区别

高级知识:

Q1: finally块什么时候执行?finally块一定会执行吗?通常在finally块执行什么?finally块执行内存优化的技巧和原因

Q2: 子类方法不应该抛出比父类方法更大范围的异常

Q3:try-catch块的使用注意事项

2. 问题解答

基础知识:

A1:

异常指的是在Java程序运行的过程中发生的一些非正常的情况或者错误,针对非正常的情况或者错误的发生,Java可以通过try-catch-finally块来捕获异常从而处理异常,使得异常发生时,程序可以通过处理异常从而恢复原来的正常状态,而不至于停止运行。错误则是在JVM层面上的错误,Java程序中不能通过try-catch-finally块来捕捉错误,也就不能使得错误发生时,通过必要的手段处理恢复正常,错误发生时程序只能停止。

A2:Java异常类的继承结构大概如下

Java面试笔记之异常处理

A3:

运行时异常通常编译器不会强制对其捕获或者处理,都是通过JVM来处理

检查异常通常编译器会强制对其捕获或者处理,发生在编译阶段

对比的表格内容如下:

类别 发生阶段 是否强制 包含异常    

运行异常

发生在程序运行时

NullPointerException(空指针异常)

ArrayStoreException(数据存储异常)

ClassCastException(类型转换异常)

 

 

 

IndexOutofBoundExcpetion(数组越界异常)

BufferOverflowException(缓冲区溢出异常)

ArithmeticException(算法异常)

 

 

 

 

 

 

检查异常

发生编译时

IOException(IO读写异常)

SQLEception(SQL异常)

 

           

A4:

try{
监控的代码块
}
catch()
{
异常处理的代码块
}
finally{
回收资源,内存优化的代码块
}

A5:

新建一个自定义异常类来继承exception类

public class ZeroException extends Exception {

    private String str;

    public void PrintStr()
    {
        System.out.println("throws ZeroException by"+str);
    }

    @Override
    public String toString() {
        return super.toString();
    }

    public void setStr(String str) {
        this.str = str;
    }

    public String getStr() {
        return str;
    }
}

然后在程序中抛出这个类,并使用try-catch处理

public class MemoryLeak {

    public static  void main(String[] args)
    {
        try{
           int c= divied(2,0);
            System.out.println("c is "+c);
        } catch (ZeroException e) {
            e.setStr("异常!被除数不能为0!分母不能为0!");
            e.PrintStr();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public static int divied(int x,int y ) throws ZeroException{

        if (y==0) {
            throw new ZeroException();
        }
        else
        {
            System.out.println("print divided by "+x/y);
            return x/y;
        }

    }

}

A6:

  1. throw通常出现在函数体内,表示要抛出这个异常。如果在某个函数声明时throws了异常,那么有需要通过try-catch块来捕获和处理异常,否则也会报错
  2. 如果某个函数内部用throw抛出了异常,那么在方法声明中一定要配套使用throws,否则会报错
  3. .throws通常出现在函数声明的位置,表示这个方法可能要抛出这个异常

高级知识

A1:针对finally的深入了解,我们可以看这一篇文章

https://blog.csdn.net/qq_39135287/article/details/78455525

A2:子类方法不应该抛出比父类方法更大的异常的原因时,由于Java的设计原则,我们默认将父类方法应该充分考虑到运行环境的险恶程度,所以需要最大的限度地来捕获和处理异常。如果子类抛出了比父类更大的范围的异常,那么子类处理了异常,父类应该怎么办呢?如果子类的抛出的异常由父类来处理,那么抛出更大的异常时,由于父类并没有定义其相关的异常处理,就无法处理子类的异常

A3: 

1. 尽量使用try-catch-finally块来处理异常,在finally块中应该尽可能的回收内存资源

2. 尽量减少try监控的代码块

3. 应该先用专业的异常来处理,再用exception来处理

4. 在catch语句块中,不要简单的抛出异常,更要尽可能的处理异常

5. 出现异常后,应当保证项目不能就此终止,要把异常造成的影响降到最低

3. 总结经验