java异常

异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。

在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。

异常体系

在这里插入图片描述

异常的根类是 java.lang.Throwable ,其下有两个子类: java.lang.Error 与 java.lang.Exception

Throwable体系:

  • Error:严重错误,无法通过处理的错误,只能事先避免。
  • Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。
    • RuntimeException是Exception的子类

Throwable中的常用方法

// 打印异常的详细信息。包含了异常的类型,异常的原因,
// 还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
void printStackTrace()

// 获取发生异常的原因。 提示给用户的时候,就提示错误原因。
String getMessage()

处理异常

throw

package com;

public class Test {

    public static void main(String[] args) {

        int[] array = {1, 2, 3};

        int value = getValue(array, 4);
        System.out.println(value);

    }


    static int getValue(int[] array, int index) {
        if (index < 0 || index > array.length - 1){
        	// throw的异常对象只能写一个
            throw new ArrayIndexOutOfBoundsException("数组越界了");
        }

        System.out.println("throw之后的代码不会继续执行了");
        return array[index];
    }
}

throws

package com;

import java.sql.SQLException;

public class Test {

    public static void main(String[] args) throws Exception {

        int[] array = {1, 2, 3};

        int value = getValue(array, 4);
        System.out.println(value);

    }

	// throws 可以抛出多个异常类
    static int getValue(int[] array, int index) throws ArrayIndexOutOfBoundsException,SQLException {

        return array[index];
    }
}

try catch

package com;

import java.io.IOException;
import java.sql.SQLException;
import java.text.ParseException;

public class Test {

    public static void main(String[] args) throws Exception {

        int[] array = {1, 2, 3};

        int value = getValue(array, 4);
        System.out.println(value);

    }


    static int getValue(int[] array, int index) {
        int i = 0;
        try {
            i = array[index];
        // 可以多catch使用
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }catch (NullPointerException e) {
            e.printStackTrace();
        } finally {
            System.out.println("无论如何都会执行的代码");
        }
        return i;
    }
}

try catch finally/resource

JAVA的一大特性就是JVM会对内部资源实现自动回收,即自动GC,给开发者带来了极大的便利。但是JVM对外部资源的引用却无法自动回收,例如数据库连接,网络连接以及输入输出IO流等,这些连接就需要我们手动去关闭,不然会导致外部资源泄露,连接池溢出以及文件被异常占用等。

try catch finally
传统的手动释放外部资源一般放在一般放在try{}catch(){}finally{}机制的finally代码块中,因为finally代码块中语句是肯定会被执行的,即保证了外部资源最后一定会被释放。同时考虑到finally代码块中也有可能出现异常,finally代码块中也有一个try{}catch(){},这种写法是经典的传统释放外部资源方法,显然是非常繁琐的。

public static void main(String[] args) {

        FileInputStream fileInputStream = null;

        try {
            fileInputStream = new FileInputStream("test");
            System.out.println(fileInputStream.read());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

try catch resource

JDK1.7之后有了try-with-resource处理机制。首先被自动关闭的资源需要实现Closeable或者AutoCloseable接口,因为只有实现了这两个接口才可以自动调用close()方法去自动关闭资源。

写法为try(){}catch(){},将要关闭的外部资源在try()中创建,catch()捕获处理异常。

其实try-with-resource机制是一种语法糖,其底层实现原理仍然是try{}catch(){}finally{}写法,不过在catch(){}代码块中有一个addSuppressed()方法,即异常抑制方法。如果业务处理和关闭连接都出现了异常,业务处理的异常会抑制关闭连接的异常,只抛出处理中的异常,仍然可以通过getSuppressed()方法获得关闭连接的异常。

public static void main(String[] args) {

        try(FileInputStream fileInputStream = new FileInputStream("test")) {
            System.out.println(fileInputStream.read());
        } catch (IOException e) {
            e.getSuppressed();
            e.printStackTrace();
        }
    }

两种异常处理的区别

如果希望产生异常后 ,方法停止运行,就用throw或throws
如果希望产生异常后 ,方法可以继续运行,就用try catch

异常注意事项

  1. 如果父类抛出多个异常,子类覆盖父类方法时,只能抛出相同的异常或者他的子集。

  2. 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类对异常,只能捕获处理,不能声明抛出。

  3. 在多异常捕获处理时,前边的类不能是后边的类的父类

  4. finally代码块一定会被执行,通常用于资源回收

自定义异常

自定义的是编译时期的异常:继承Exception

自定义的是运行时期的异常:继承RuntimeException

自定义基础异常

package com.lxit.testnginx.testnginx;
import org.springframework.http.HttpStatus;

/**
 *基础异常,谁定义异常就继承它
 */
public class BasicException extends RuntimeException {

	/**
	 * 错误状态码
	 * spring-boot
	 * package org.springframework.http;
	 * public enum HttpStatus {
	 * OK(200, "OK"),
	 */
	private HttpStatus status;

	public BasicException(String message, HttpStatus status) {
		super(message);
		this.status = status;
	}

	public HttpStatus getStatus() {
		return status;
	}

	public void setStatus(HttpStatus status) {
		this.status = status;
	}
}

使用自定义基础异常

package com.lxit.testnginx.testnginx;

import org.springframework.http.HttpStatus;


public class FileStorageException extends BasicException {

	public FileStorageException(String message) {
		super(message, HttpStatus.NOT_FOUND);
	}

}

测试

package com.lxit.testnginx.testnginx;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus;

@SpringBootTest
class TestnginxApplicationTests {

	@Test
	void contextLoads() {

		String s = null;

		if (s == null){
			FileStorageException fileStorageException = new FileStorageException("文件找不到异常");
			// 404 NOT_FOUND
			System.out.println(fileStorageException.getStatus());
			throw fileStorageException;
		}
	}

}

面试题

try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

package com.example.javasestudy.exception;

public class TryCatchReturn {

    public static void main(String[] args) {
    	// finally 在 return之后执行
    	// 如果finally中也有return,那么返回值就是finally中的return
        System.out.println(test());
    }


    public static int test(){
        int x = 1;

        try{
            return x;
        }finally {
            ++x;
        }
    }
}

常见的runtime expection

NullPointerException - 空指针引用异常
ClassCastException - 类型强制转换异常。
ArithmeticException - 算术运算异常
IndexOutOfBoundsException - 下标越界异常
SQLException:操作数据库异常
IOException:输入输出异常

新的淤青是茄子绀或虾红色,旧的淤青是狐狸或貂毛,老茶的颜色。

房思琪的初恋乐园
林奕含

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值