java中的异常

本文详细介绍了Java中的Error和Exception异常体系,区分了它们的区别,以及在Spring中如何使用@ControllerAdvice和@ExceptionHandler处理自定义异常。此外,讨论了try-catch-finally的使用、线程池中InterruptedException的处理等。
摘要由CSDN通过智能技术生成

java中的异常体系

在这里插入图片描述
java.lang.Throwable 是java的顶层类,它的子类error和exception都是继承它的,Exception的代码很简单基本上都是调用了super的代码。error同理。

public class Error extends Throwable {
    static final long serialVersionUID = 4980196508277280342L;

    /**
     * Constructs a new error with {@code null} as its detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     */
    public Error() {
        super();
    }

    /**
     * Constructs a new error with the specified detail message.  The
     * cause is not initialized, and may subsequently be initialized by
     * a call to {@link #initCause}.
     *
     * @param   message   the detail message. The detail message is saved for
     *          later retrieval by the {@link #getMessage()} method.
     */
    public Error(String message) {
        super(message);
    }

    /**
     * Constructs a new error with the specified detail message and
     * cause.  <p>Note that the detail message associated with
     * {@code cause} is <i>not</i> automatically incorporated in
     * this error's detail message.
     *
     * @param  message the detail message (which is saved for later retrieval
     *         by the {@link #getMessage()} method).
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A {@code null} value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Error(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Constructs a new error with the specified cause and a detail
     * message of {@code (cause==null ? null : cause.toString())} (which
     * typically contains the class and detail message of {@code cause}).
     * This constructor is useful for errors that are little more than
     * wrappers for other throwables.
     *
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A {@code null} value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Error(Throwable cause) {
        super(cause);
    }

    /**
     * Constructs a new error with the specified detail message,
     * cause, suppression enabled or disabled, and writable stack
     * trace enabled or disabled.
     *
     * @param  message the detail message.
     * @param cause the cause.  (A {@code null} value is permitted,
     * and indicates that the cause is nonexistent or unknown.)
     * @param enableSuppression whether or not suppression is enabled
     *                          or disabled
     * @param writableStackTrace whether or not the stack trace should
     *                           be writable
     *
     * @since 1.7
     */
    protected Error(String message, Throwable cause,
                    boolean enableSuppression,
                    boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
public class Exception extends Throwable {
    static final long serialVersionUID = -3387516993124229948L;

    public Exception() {
        super();
    }

    public Exception(String message) {
        super(message);
    }

    public Exception(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Constructs a new exception with the specified cause and a detail
     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
     * typically contains the class and detail message of <tt>cause</tt>).
     * This constructor is useful for exceptions that are little more than
     * wrappers for other throwables (for example, {@link
     * java.security.PrivilegedActionException}).
     *
     * @param  cause the cause (which is saved for later retrieval by the
     *         {@link #getCause()} method).  (A <tt>null</tt> value is
     *         permitted, and indicates that the cause is nonexistent or
     *         unknown.)
     * @since  1.4
     */
    public Exception(Throwable cause) {
        super(cause);
    }

    /**
     * Constructs a new exception with the specified detail message,
     * cause, suppression enabled or disabled, and writable stack
     * trace enabled or disabled.
     *
     * @param  message the detail message.
     * @param cause the cause.  (A {@code null} value is permitted,
     * and indicates that the cause is nonexistent or unknown.)
     * @param enableSuppression whether or not suppression is enabled
     *                          or disabled
     * @param writableStackTrace whether or not the stack trace should
     *                           be writable
     * @since 1.7
     */
    protected Exception(String message, Throwable cause,
                        boolean enableSuppression,
                        boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

error

error是程序运行,一般有oom stackoverflow等 ,属于程序异常,不属于bug,属于程序异常,需要手动处理,一般是资源受限,死锁等问题造成的。
StackOverflowError和OOM

  • OOM异常需要到JVM那块 暂时先不写了

exception

包含为受检异常和运行异常 (编译时异常和运行时异常),前者在编译前就要检查是否有可能产生编译时异常;后者是在编译后运行时才会判断的异常。
受检异常:idea会提醒你可能得异常,你需要处理才能正常编译,可以throws或者try catch。常见的有IOException:
SQLException
ClassNotFoundException
InterruptedException
ParseException
NoSuchMethodException
FileNotFoundException
在这里插入图片描述
运行时异常:可以正常编译运行,我们需要注意这种异常。这种异常是属于代码的bug。常见的有NullPointerException,ArrayIndexOutOfBoundsException,
IllegalArgumentException,
IllegalStateException,
ClassCastException
在这里插入图片描述
我们也可以自定义异常,例如

public class MyNullpointException extends NullPointerException{
    public MyNullpointException(String s) {
        super(s);
    }
}

在spring中我们可以定义全局异常

@ControllerAdvice
public class GlobalExceptionHandler {

    // 捕获自定义异常 MyNullpointException
    @ExceptionHandler(MyNullpointException.class)
    public ResponseEntity<String> handleCustomException(MyNullpointException ex) {
        // 可以根据需要进行异常处理逻辑
        String errorMessage = "Custom Exception occurred: " + ex.getMessage();
        System.out.println(errorMessage);
        return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    // 捕获其他未处理的异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleOtherExceptions(Exception ex) {
        // 可以根据需要进行异常处理逻辑
        String errorMessage = "An error occurred: " + ex.getMessage()+ex.getStackTrace().toString()+ex.getCause().toString();
        System.out.println(errorMessage);
        return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

可以参考这个 git地址:

https://gitee.com/sunweibo5/demo/tree/master/src/main/java/com/example/demo/service/exceptions

对于异常的处理

主要包含 throws throw try catch finally这几个关键字。
我们可以主动抛异常

throw new NullPointerException();

主动抛出的异常 有两种处理方式 一种是try catch,去处理这个异常; 一种是thows 把这个异常抛出去给上层 让上层去处理。
常见的几种try catch finally的关系 下面代码分析一下

public static int test(){
        System.out.println("try 中return");
            int i= 1;
        try{
            System.out.println("try");
            i++;
            System.out.println("i:"+i);
            return i;
        }catch (Exception e){
            System.out.println("catch");
            return i++;
        }finally{
            System.out.println("finally");
            i++;
            System.out.println("i:"+i);

        }


    }


    public static int test2(){
        System.out.println("try 和 finally中同时return");
        int i= 1;
        try{
            System.out.println("try");
            i++;
            System.out.println("i:"+i);
            return i;
        }catch (Exception e){
            System.out.println("catch");
            return 2;
        }finally{
            System.out.println("finally");
            i++;
            System.out.println("i:"+i);
            return i;
        }
        //小心这里,可能会出现不可达的情况,比如finally中有return,或者try/catch都有return
    }

    public static int test3(){
        System.out.println("catch 和 finally中同时return");
        int i= 1;
        try{
            System.out.println("try");
            i++;
            System.out.println("i:"+i);
            throw new NullPointerException();

        }catch (Exception e){
            System.out.println("catch");
            i++;
            System.out.println("i:"+i);
            return i;
        }finally{
            System.out.println("finally");
            i++;
            System.out.println("i:"+i);
            return i;
        }
        //小心这里,可能会出现不可达的情况,比如finally中有return,或者try/catch都有return
    }

        public static void main(String[] args){
            System.out.println("返回值:"+test());
            System.out.println("返回值:"+test2());
            System.out.println("返回值:"+test3());
            //主函数执行错误以后  就会到catch块  继续执行错误的话就会到
        }

执行结果

try 中return
try
i:2
finally
i:3
返回值:2
try 和 finally中同时return
try
i:2
finally
i:3
返回值:3
catch 和 finally中同时return
try
i:2
catch
i:3
finally
i:4
返回值:4

try中有return,finally一定会执行。
try中有return, 会先将值暂存,无论finally语句中对该值做什么处理,最终返回的都是try语句中的暂存值。
当try,catch,finally语句中均有return语句,会忽略try中return。

还有一些情况

  public static int test4(){
            System.out.println("catch中报错 finally不返回");
            try{
                Integer.parseInt("execption");
                System.out.println("try");
            }catch (Exception e){
                System.out.println("catch");
                Integer.parseInt("execption");
                //System.exit(0);//取消的话直接退出

            }finally{
                System.out.println("finally");

            }
            return 666;
        }
   运行结果:
     catch中报错 finally不返回
 	catch
 	finally
Exception in thread "main" java.lang.NumberFormatException: For input string: "execption"
 at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
 at java.lang.Integer.parseInt(Integer.java:580)
 at java.lang.Integer.parseInt(Integer.java:615)
 at com.example.demo.service.关键字.finallyy.Test.test4(Test.java:12)
 at com.example.demo.service.关键字.finallyy.Test.main(Test.java:112)
 public static int test5(){
        System.out.println("catch中报错 finally又返回");
        try{
            Integer.parseInt("execption");
            System.out.println("try");
        }catch (Exception e){
            System.out.println("catch");
            Integer.parseInt("execption");
            //System.exit(0);//取消的话直接退出

        }finally{
            System.out.println("finally");
            return 666;
        }

    }

运行结果

catch中报错 finally又返回
catch
finally
返回值:666

对于有返回值的函数,当catch中有报错,finally没有返回值,会将整个错误抛出来;如果有返回值 就不会报错

  public static int test6() {
        try {
            // do something
        } catch (Exception e) {
            // handle exception
            throw new NullPointerException("An error occurred while handling the exception.");
        } finally {
            // do something else
            int i = 1/0;
        }
        return 1;
    }

结果

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.example.demo.service.关键字.finallyy.Test.test6(Test.java:30)
	at com.example.demo.service.关键字.finallyy.Test.main(Test.java:126)

当异常发生时,程序将会跳转到catch块中,并抛出一个自定义异常CustomException。然后,程序将会执行finally块中的代码,其中包含除零操作,导致又抛出了一个新的异常ArithmeticException。

由于finally块中的异常将覆盖之前的异常,因此最终的异常将是ArithmeticException

线程池抛异常如何处理

InterruptedException 是 Java 中的一个异常类,它表示一个线程被中断的异常情况。当一个线程在等待、睡眠或者被阻塞时,另一个线程可以调用 interrupt() 方法来中断这个线程,即使这个线程没有主动调用可中断方法也可以中断它。

当一个线程被中断时,如果该线程正在执行一个可中断的操作(例如调用 sleep()、wait()、join() 等方法),或者调用了 Object 类的 wait()、wait(long)、wait(long, int)、join()、join(long)、join(long, int)、sleep() 方法中的其中一个,或者调用了 Thread 类的 sleep()、join()、join(long)、join(long, int) 方法,那么该线程会抛出 InterruptedException 异常。

一般来说,当线程收到 InterruptedException 异常时,应该在异常处理中进行适当的清理工作,然后退出或者恢复线程的运行,具体处理方式取决于应用的需求和设计。

在多线程编程中,处理 InterruptedException 异常是非常重要的,因为它涉及到线程的中断和恢复,而且在某些情况下可能会影响到程序的正确性和性能。

  • 32
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值