java异常

本文详细介绍了Java中的异常处理机制,包括Throwable、Error、Exception的概念及区别,throw与throws的使用方式,以及如何自定义异常。此外,还探讨了try-catch-finally结构的应用场景和特殊行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class Throwable extends Object implements Serializable :Throwable 类是 Java 语言中所有错误或异常的超类。
public class Error extends Throwable:Error类 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。
public class Exception extends Throwable :Exception 类及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件。
Exception又分为:
                  编译期问题:不是RuntimeException的异常。必须进行处理,如果不处理,编译就不能通过。
                  运行期问题:RuntimeException。这种异常不进行处理,出现问题是编写的代码不严谨。
这里写图片描述

Throwable中的方法:
getMessage():获取异常信息,返回字符串。
toString():获取异常类名和异常信息,返回字符串。
printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。


throw和throws的区别是什么?
throws:
            用在方法声明后面,跟的是异常类名
            可以跟多个异常类名,用逗号隔开
            表示抛出异常,由该方法的调用者来处理
            throws表示出现异常的一种可能性,并不一定会发生这些异常
throw
            用在方法体内,跟的是异常对象名
            只能抛出一个异常对象名
            表示抛出异常,由方法体内的语句处理
            throw则是抛出了异常,执行throw则一定抛出了某种异常

public class ThrowDemo {
    public static void main(String[] args) {
        method();
    }

    public static void method() {
        int a = 10;
        int b = 0;
        if (b == 0) {
            throw new ArithmeticException();    // throw:方法内部,抛出异常对象
        } else {
            System.out.println(a / b);
        }
    }
}



异常的处理
1、JVM的默认处理:JVM会把异常的名称,原因,位置等信息输出在控制台,但是程序就不能运行了
2、由编码人员自己处理:
    (1)通过try……catch……finally编写处理代码。这样后面的程序可以继续执行,不像JVM处理一样就直接退出了。
    (2)throws:把处理不了的在方法上抛出声明,这样子调用者调用这个方法的时候就必须处理了这个异常了。
区别:
        后续程序需要继续运行就try。
        后续程序不需要继续运行就throws,因为调用了throws就相当于交给JVM处理,JVM就会停止程序,而不会执行这个后面的代码。


编译期异常必须要处理,否则编译不通过。
运行期异常可以不处理,也可以处理。

编译期异常的抛出,将来调用者调用它的时候就必须处理。
运行期异常的抛出,将来调用者调用它的时候可以不处理。


被finally控制的语句总是会执行么?
不一定。一般情况下被finally控制的语句体一定会执行。特殊情况:如果在执行finally之前JVM退出了(System.exit(0)),就不会执行了。


finally的作用是什么?
用于释放资源,在IO流操作和数据库操作中会用到


final,finally和finalize的区别是什么?
final:可以修饰类、成员变量、成员方法
           修饰类:类不能被继承
           修饰变量:变量是常量
           修饰方法:方法不能被重写
finally:是异常处理的一部分,用于释放资源。一般来说finally控制的代码肯定会执行,特殊情况:在执行到finally之前JVM退出了finally控制的代码就不会执行
finalize:是Object类的一个方法,用于垃圾回收。



如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问是在return前还是return后。?
会。在return前面执行。但是准确的说,是在return中间执行。
通过调试,我们可以发现程序是这么执行的:

public class FinallyDemo {
    public static void main(String[] args) {
        System.out.println(getInt());                      //1   //9(控制台输出30)
    }

    public static int getInt(){
        int a = 10;                                        //2 
        try{
            System.out.println(a / 0);                     //3(异常了,直接去执行catch)         
            a = 20;
        }catch(ArithmeticException e){                     //4
            a = 30;                                        //5
            return a;                                      //6      //8
            //程序在执行到这一步的时候,这里不是return a而是return 30,这个返回路径就形成了。但是发现后面有finally,继续执行finally的内容,然后回到以前的返回路径,继续走return 30
        }finally{
            a = 40;                                        //7(执行完之后,继续回到之前的返回路径)
        }
        return a;
    }
}

但是如果也在finally之后加个return呢?这个时候输出的就是40了。

public class FinallyDemo {
    public static void main(String[] args) {
        System.out.println(getInt());                      //1   //9(控制台输出40)
    }

    public static int getInt(){
        int a = 10;                                        //2 
        try{
            System.out.println(a / 0);                     //3(异常了,直接去执行catch)                      
            a = 20;
        }catch(ArithmeticException e){                     //4
            a = 30;                                        //5
            return a;                                      //6
        }finally{
            a = 40;                                        //7
            return a;                                      //8
        }
    }
}



异常类还可以自己编写,那么具体是怎么弄得呢?
自定义异常:
1、继承自Exception(编译期异常)
2、继承自RuntimeException(运行期异常)

自定义一个编译器异常类:

public class MyException extends Exception {
    public MyException() {

    }

    //为了能够输出异常信息,创建有参构造,提供参数传递
    public MyException(String message) {
        super(message);
    }
}

自定义测试类如下:

public class Student {
    public void check(int age) throws MyException{
        if(age > 40 || age < 10){
            throw new MyException("年龄必须在10到40之间");    //调用自定义异常类的代餐构造,用来输出异常信息
        }else{
            System.out.println("正常");
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入年龄:");
        int age = sc.nextInt();

        Student student = new Student();
        try {
            student.check(age);
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}

当输入的数据不符合要求的时候,会在控制台打印异常信息:

请输入年龄:
123
org.danni.demo1.MyException: 年龄必须在1040之间
    at org.danni.demo1.Student.check(Student.java:8)
    at org.danni.demo1.Student.main(Student.java:20)



注意:
1、子类覆盖父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。
2、如果父类抛出了多个异常,子类覆盖父类时,只能抛出相同的异常或者是它的子集,子类不能抛出父类没有的异常
3、如果被覆盖的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值