JavaSE面试要点四——异常

异常

异常的概念

    我对异常的理解的概念就是不正常的意思。在Java中,异常指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。当然异常指的不是语法错误,语法报错,根本不可能编译成字节码文件从而去运行。
    在Java中,异常本身就是一个类,产生异常就是创建异常对象并抛出。Java处理异常的方式就是中断处理

异常的分类

在这里插入图片描述
    可以看出 Throwable 是所有异常的父类,它定义了异常的概念和约束,子类有ErrorException分类

    Error: 严重错误Error,无法通过处理的错误,只能事先避免,好比绝症。比如JVM系统内部保存、资源耗尽等严重情况。一般不编写针对性的代码进行处理
    Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理

异常的体系

异常体系分为运行期异常编译期异常两种

  1. 运行期异常: 程序运行时抛除的异常,所有RuntimeException的子类都 是运行期异常,比如数学异常 、空指针异常 、 数组下标越界、等等…
  2. 编译期异常: 除去运行期的异常都是编译期异常, 也称为检测异常(也就是编译器在你敲完一段代码后打红线的部分)

在这里插入图片描述
在这里插入图片描述

Throwable中的常用方法

  1. public void printStackTrace() 打印异常的详细信息。
  2. public String getMessage() 获取发生异常的原因。
  3. public String toString() 获取异常的类型和异常描述信息(不用)。

异常的处理

try、catch和finally

    如果异常出现的话,会立刻终止程序,所以我们得处理异常。异常的捕获和处理需要采用try和catch来处理:

	try {
	
	} catch (OneException e) {
	
	} catch (TwoException e) {
	
	} finally {
	
	}

或者

try{
     编写可能会出现异常的代码
}catch(异常类型  e){
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常
}
  1. try中包含了可能产生异常的代码
  2. try后面是catchcatch可以有一个或多个,catch中是需要捕获的异常
  3. try中的代码出现异常时,出现异常下面的代码不会执行,马上会跳转到相应的catch语句块中,如果没有异常不会跳转到catch
  4. finally表示,不管是出现异常,还是没有出现异常,finally里的代码都执行,finally和catch可以分开使用,但finally必须和try一块使用,只有tryfinally也是可以的

异常捕获的顺序

    异常的捕获:一般按照由小到大的顺序,也就是先截获子异常,再截获父异常
在这里插入图片描述
    将IOException放到前面,会出现编译问题,因为IOException是FileNotFoundException的父类,所以截获了IOException异常后,IOException的子异常都不会执行到,所以再次截获FileNotFoundException没有任何意义。异常的截获一般按照由小到大的顺序,也就是先截获子异常,再截获父异常。close()都是写在finally,这里为了区分异常捕获的顺序所以不严谨)

throws抛出

    在定义方法时,如果方法体中有受检(编译时)异常需要预处理,可以捕获处理,也可以抛出处理。抛出异常的方法一般都不是定义在底层,底层的方法都需要去try、catch、finally异常。

    throw它用来抛出一个指定的异常对象。那么,抛出一个异常具体如何操作呢?

  1. 创建一个异常对象。封装一些提示信息(信息可以自己编写)。
  2. 需要将这个异常对象告知给调用者。通过关键字throw就可以完成。throw 异常对象。
throw new 异常类名(参数);
throw new NullPointerException("要访问的arr数组不存在");

throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");
  1. 谁调用这个方法,谁负责处理该异常(或者再次抛出…继续等下一个怨种方法处理…(不建议,当然写在main方法问题不大))
  2. 在定义方法时,把异常抛出就是为了提醒方法的使用者,有异常需要预处理

自定义异常

    自定义异常就是自己定义的异常类 ,也就是API中的标准异常类的直接或间接的子类。自定义异常类中往往不写其他方法,只重载需要使用的构造方法。继承Exception,在方法中使用throw抛出后,必须在方法中try-catch或 throws抛出。

public class DemoCreatThrow extends Exception{
    public DemoCreatThrow(){
        super();
    }
    public DemoCreatThrow(String a){
        super(a);
    }
}

代码:

class DemoThrow1{
    public static void main(String[] args) {
        try{
            System.out.println(m1(10,0));
        } catch (DemoCreatThrow e) {
            e.printStackTrace();
        }
    }
    public static int m1(int a,int b) throws DemoCreatThrow {
        if(b==0){
            throw new DemoCreatThrow("自定义的异常");
        }
        return a/b;
    }
}

在这里插入图片描述

方法重写中的异常处理(父类捕获子类异常)

    子类方法的异常要比父类方法的异常更小,这要符合继承的规则:子类方法的访问权限可以更宽泛(更大),子类方法的异常要比父类方法的异常更小,所以父线程可以捕获子线程的异常。

异常的刨根问底

java异常的处理机制

    Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为 java.lang.Throwable,Throwable下面又派生了两个子类:ErrorException

  1. Error:表示应用程序本身无法克服和恢复的一种严重问题。(不编写代码来处理)
  2. Exception:表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常。(可以使用针对的代码处理)
    运行期异常:程序运行时抛除的异常,所有RuntimeException的子类都 是运行期异常,比如数学异常 、空指针异常 、 数组下标越界、等等…
    编译期异常:除去运行期的异常都是编译期异常, 也称为检测异常(也就是编译器在你敲完一段代码后打红线的部分)

throw和throws的区别

throw:

throw 语句用在方法体内,表示抛出异常,由方法体内的语句处理。
throw是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行throw一定是抛出了某种异常。
throw一般用于抛出自定义或者具体的异常。

throws:

throws语句是用在方法声明后面,表示如果抛出异常,由该方法的调用者来进行异常的处理。
throws主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型。
throws表示出现异常的一种可能性,并不一定会发生这种异常。

final、finally、finalize 的区别?

  1. final: 用于声明属性,方法和类,分别表示属性不可变,方法不可重写,被其修饰的类不可继承。
  2. finally: 异常处理语句结构的一部分,表示总是执行。必须与try一起使用
  3. finalize: 垃圾回收此对象之前,总会先调 用这个对象的 finalize()方法,一个对象的 finalize()方法只被调用一次。在 finalize()时可能会导致对象复活

Java中异常分为哪些种类?

运行时异常和编译期异常(看上面)

error和exception的区别?

首先,他们的父类都是Throwable。
Error是你自己不能解决的,Exception是可以解决的(看上面)

说出最常见的5个RuntimeException?

  1. java.lang.NullPointerException 空指针异常;出现原因:调用了未经初始化的对象或者是不存在的对象
  2. java.lang.ClassCastException 数据类型转换异常
  3. java.lang.ClassNotFoundException 指定的类找不到;出现原因:类的名称和路径加载错误;通常都是程序试图通过字符串来加载某个类时可能引发异常
  4. java.lang.NoSuchMethodException 方法不存在异常
  5. java.lang.NumberFormatException 字符串转换为数字异常;出现原因:字符型数据中包含非数字型字符
  6. java.lang.IndexOutOfBoundsException 数组角标越界异常,常见于操作数组对象时发生

java 中如何编写自定义异常?

看上面

父线程可以捕获子线程的异常么?

可以(看上面)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值