java异常

1 -基本概念

        异常,指不正常,在Java中异常处理机制能让程序在异常情况发生时,按照实现设定好的异常逻辑有针对性的处理出现的异常。

        java.lang.Throwable类是Java中所有错误和异常的超类,已知直接子类有:Error类和Exception类。 

异常的层次结构 


2 - 异常的主要分类

java.lang.Exception类是所有异常类的超类

名称说明
RuntimeException运行时异常类,也叫作非检测性异常
IOExceptionIO异常类,也叫作检测性异常

RuntimeException类的主要子类

异常类型说明
AritmeticException算数异常
ArrayIndexOutofBoundsException数组下标越界异常(间接子类)
NullPointException空指针异常
ClassCastException类型转换异常
NumberFormatException数字格式异常(间接子类)

注意:

        当程序执行中产生异常并没有手动处理时,则采用默认处理方法,默认处理方法的方式就是:打印异常名称、异常原因、异常位置等相关信息,并终止程序,导致后续代码无法执行。

运行时异常的处理

        绝大多数的运行时异常/非检测性异常都可以采用if判断的方式避免发生。

/**
 * @author Mr.乐
 * @data 2022/8/5  23:03
 */
public class Demo01 {
    public static void main(String[] args) {
        //运行时异常通常可以通过if判断的方式避免掉
        int a = 10;
        int b = 0;
        if(b != 0){
            System.out.println(a / b); //java.lang.ArithmeticException
        }

        int[] arr = new int[5];
        int pos = 5;
        if(pos < 5 && pos >= 0){
            System.out.println(arr[pos]);//java.lang.ArrayIndexOutOfBoundsException
        }

        String s1 = null;
        if(s1 != null){
            System.out.println(s1.length());//java.lang.NullPointerException
        }

        Exception e = new Exception();
        if (e instanceof IOException){//判断e是否属于IOException的类型
            IOException io = (IOException) e; //java.lang.ClassCastException
        }

        String s2 = "123abc";
        if(s2.matches("\\d+")){//判断字符串内部是否是数字格式
            System.out.println(Integer.parseInt(s2));//java.lang.NumberFormatException
        }
    }
}

3 - 异常的捕获格式

语法格式:
    try{
        编写可能会产生异常的语句块;
    }catch(异常的类型 引用){
        编写针对该异常的处理语句;
    }finally{
        无论是否发生异常都需要执行的语句块;
    }


4 - 异常执行流程

/**
 * @author Mr.乐
 * @data 2022/8/5  23:47
 */
public class Demo02 {
    public static void main(String[] args) {
        try{
            System.out.println("a");
            FileInputStream fis = new FileInputStream("./aa.txt");
            System.out.println("b");
        }catch (FileNotFoundException e){
            System.out.println("c");
//            System.out.println("异常真的出现了,我的处理办法是,按兵不动!");
            e.printStackTrace();
        }finally {
            System.out.println("d");
        }
        System.out.println("e");
        //没有异常情况时:  a   b   d   e
        //有异常情况时:  a   c   d   e
    }
}

finally中通常编写无论是否异常发生都会执行的代码,因此通常用来做善后处理,比如:关闭流,关闭数据库连接。

当多个catch同时出现的情况下,需要将小的异常类型放在打的类型的上面。

/**
 * @author Mr.乐
 * @data 2022/8/6  0:25
 */
public class Demo03 {
    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("./a.txt");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

 5 - 手动抛出异常

在某些特殊场合中,对于出现的异常无法直接处理或者不便于处理时,就可以选择将异常转移给调用方法这,这种形式叫做异常的抛出。

/**
 * @author Mr.乐
 * @data 2022/8/6  0:25
 */
public class Demo04 {
    public static void show() throws FileNotFoundException {
        FileInputStream fis = new FileInputStream("./a.txt");
    }

    public static void main(String[] args) {
        try {
            Demo04.show();//抛出的异常会抛给方法的调用者
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //异常一旦抛到了主方法中,建议进行捕获,如果不捕获(处理)的情况下,选择抛出就会抛给JVM,会增加JVM的负担
    }
}

        在子类中,如果父类被重写的方法抛出了异常,那么子类中重写的方法可以抛出更小的异常、一样的异常,但是不可以抛出更大的异常。

/**
 * @author Mr.乐
 * @data 2022/8/6  0:28
 */
public class Demo05 {
    public void show() throws IOException {
        System.out.println("我是Demo05中的show方法");
    }

    /*
    在子类中,如果父类被重写的方法抛出了异常,那么子类中重写的方法可以抛出更小的异常、一样的异常,
    但是不可以抛出更大的异常。
    * */
}
--------------------------------------------------------------------------------
/**
 * @author Mr.乐
 * @data 2022/8/6  0:38
 */
public class Demo05Sub extends Demo05 {
    //重写的父类方法会将方法中的异常类型一同重写到子类方法中

    @Override
    public void show() throws IOException {
        super.show();
    }

//    @Override
//    public void show() throws FileNotFoundException {//子类可以抛出比父类更小的异常
//    }

//    @Override
//    public void show() throws Exception {//子类不可以抛出比父类更大的异常
//    }
}

6 - 自定义异常

自定义异常类的方式

        自定义类去继承于Exception类或者其子类,提供两个版本的构造方法,一个是无参的,一个是String类型的有参构造。

public class AgeException extends Exception{
    //提供无参构造

    public AgeException() {
    }

    //提供有参,并且是String类型参数的构造方法
    public AgeException(String message) {
        super(message);//将参数传递给父类的构造方法,目的是打印传递的参数
    }
}
---------------------------------------------------------------------------
/**
 * @author Mr.乐
 * @data 2022/8/6  0:52
 */
public class Student {
    private String name;
    private int age;
    public Student() {
    }

    public Student(String name, int age) {
//        this.name = name;
//        this.age = age;
        setName(name);
        //在构造方法中将异常捕获
        try {
            setAge(age);
        } catch (AgeException e) {
            e.printStackTrace();
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) throws AgeException {//188
        //做学生年龄的合理判断,如果年龄不合理,则抛出自定义异常
        if (age < 0 || age > 150){
            //抛出自定义年龄异常
            throw new AgeException("年龄不合理");//异常抛出
        }else{
            this.age = age;//年龄合理则进行正常的赋值
        }
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
--------------------------------------------------------------------
public class TestStudent {
    public static void main(String[] args) {
        //Student类初始化
        Student stu = new Student("Smith", 188);
        System.out.println(stu);//打印对象引用,调用的是Student类中重写的toString方法,打印内容
    }
}

7 - final、finally、finalize的区别

方法名说明
final修饰的变量不可修改、方法不可重写、类不能被继承
finally异常处理机制中的一个关键字(用作善守处理)
finalize垃圾收集器执行之前被自动调用的方法
/**
 * @author Mr.乐
 * @data 2022/8/6  1:10
 */
public class Demo06 {
    public final static String name = "Andy";//使用final定义变量

    public /*final*/ void show(){//不可被重写
        System.out.println("我是被final修饰的方法");
    }

    @Override//垃圾收集器启动前,自动调用的方法
    protected void finalize() throws Throwable {
        System.out.println("我是finalize方法,被自动调用了");
    }

    public static void main(String[] args) {
//        name = "Smith";//常量不可被修改
        Demo06 dd = new Demo06();
        dd = null;//把引用类型复制为null类型
        System.gc();//启动垃圾回收机制
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.乐.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值