[Java基础]—异常

124 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

异常

Throwable类

java把异常当做对象来处理,java.lang.Throwable作为所有异常的超类

分类

Error

Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。

Exception

Excetion一般是由程序逻辑错误引起,程序可以从逻辑角度尽可能避免这类异常的发生;

运行时异常

  • RuntimeException(运行时异常)

非运行时异常

  • ArrayIndexOutOfBoundsException(数组下标越界)
  • NullPointerException(空指针异常)
  • ArithmeticException(算术异常)
  • MissingResourceException(丢失资源)
  • ClassNotFoundException(找不到类) 这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。

区别

  • Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程。
  • Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

异常处理机制

捕获异常

  • try catch 结构
  • try catch finally结构

在执行a/b时,由于0不能作为除数,即报出ArithmeticException异常

public class Test {
    public static void main(String[] args) {
        int a=1;
        int b=0;
        System.out.println(a/b);
    }
}

image-20220320173443356 根据ArithmeticException类型进行异常捕获,快捷键:Ctrl+Alt+T

public class Test {
    public static void main(String[] args) {
        int a=1;
        int b=0;
        try {   								//try监控区域
            System.out.println(a/b);
        } catch (ArithmeticException e) { 		//catch(想要捕获的异常类型)
            System.out.println("算数异常");
        } finally { 							//finally 关闭捕获防止资源占用
            System.out.println("finally");
        }
    }
}
//结果:
算术异常
finally

若需要多个捕获异常则异常需要从小到大排序Throwable > Exception = Error > ArithmeticException……,如下若Throwable、Exception互换则会编译出错

public class Test {
    public static void main(String[] args) {
        int a=1;
        int b=0;
        try { //try监控区域
            System.out.println(a/b);
        } catch (Error e) { //catch(想要捕获的异常类型)
            System.out.println("Error");
        } catch (Exception e){
            System.out.println("Exception");
        } catch (Throwable e){
            System.out.println("Throwable");
        }
    }
}
//结果
Exception

image-20220320182103522

抛出异常

  • throw

    throw用在方法内

  • throws

    throws用在方法声明后

public class Test {
    public static void main(String[] args) {
    new Test().test(1,0); //匿名内部类

    }
    public void test(int a,int b) {
        if(b==0){
            throw new ArithmeticException(); //throw方法内抛出异常
        }
    }
}

image-20220320181800305 throws在方法上抛出异常,使用时一般需要异常捕获

public class Test {
    public static void main(String[] args) {
        try {
            new Test().test(1,0); //匿名内部类
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }

    }
    public void test(int a,int b) throws ArithmeticException{
        if(b==0){
            throw new ArithmeticException(); //throw方法内抛出异常
        }
    }
}

自定义异常

自定义异常必须继承Exception类或RuntimeException类

public class MyException {
    public static void main(String[] args) {
        new MyException().test(110);
    }
    
    public void test(int a){
        if(a>120||a<10){
            throw new AgeException("年龄需要在10-120之间");
        }
        System.out.println("输入正确");
    }
}
class AgeException  extends RuntimeException{
    public AgeException(String message) {
        super(message);
    }

}

一般情况下,继承RuntimeException类,因为可以使用默认的处理机制,若继承Exception则需要再用throws抛出,即:

public class MyException {
    public static void main(String[] args) throws AgeException {
        new MyException().test(110);
    }
    
    public void test(int a){
        if(a>120||a<10){
            throw new AgeException("年龄需要在10-120之间");
        }
        System.out.println("输入正确");
    }
}
class AgeException  extends Exception{
    public AgeException(String message) {
        super(message);
    }
}