Java面试笔记之异常处理

针对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异常类的继承结构大概如下

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. 总结经验

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章