008—Java中的异常知识详情

前奏:

注解: 注释 给编译器看
    @Override: 判断方法是否重写(用于校验是否重写  如果不符合重写规范就会报错)
    @Deprecated:标记过时 
    @SuppressWarnings("all"): 抑制警告   (可以有参数)

异常的知识体系:

 异常的体系:

                 Throwable

                         -- Error 错误 不能处理的

                         -- Exception 异常

                                 -- 运行时异常 代码真正跑起来

                                 -- 编译时异常 写完代码就报错

 

 Error:

import org.junit.Test;

public class TestError {
    @Test
    public void test01(){
        a();
    }

    private void a() {
        a();
    }

}

 

@Test
    public void test2(){

    int arr [] = new int[21_0000_0000];
        System.out.println(Arrays.toString(arr));
        
    }

 

 Error:

         StackOverflowError

         OutOfMemoryError

 RunTimeException(运行时异常)

  •   ArithmeticException:算数异常

  •           除数为0

  • NullPointerException

  • ClassCastException

  • ArrayIndexOutofBoundsException

  • InputMismatchException: 输入不匹配异常

 CompilerException(编译时异常)

FileNotFoundException
InterruptedException

异常的抛出机制

向下执行  向上抛出

public class TestException {
    public static void main(String[] args) {
        method01();
    }
    private static void method01() {
        method02();
    }
    private static void method02() {
        method03();
    }
    private static void method03() {

        method04();
    }
    private static void method04() {

        int[] arr = {10,20};

        System.out.println(arr[23]);

        System.out.println("Game Over");
    }
}

 有图可知,jvm由main方法进入程序开始i执行method01(),进行连续调用method02(),method03(),method04(),此时出现异常,jvm会看一下当前又没有对异常的处理,如果没有则向上抛到method03(),继而抛到method02(),method01(),最后到达main()方法,如果此时还没有处理,那么就会抛给JVM虚拟机

因此再查看异常信息的时候,要从上往下看,最上边的是异常的发源地。

 ThrowException测试(手动抛出异常)

public class ThrowTest {
    public static void main(String[] args) {
        int [] arr = {10,20,40,20};
//        method(null);
        method(arr);
    }

    private static void method(int[] arr) {
        if (arr == null){
            throw new NullPointerException("空指针异常");
        }
        if (arr.length > 3){
            throw new ArrayIndexOutOfBoundsException("数组下标越界");
        }
    }
}

异常的处理方式

        try-catch测试(即使发生异常了,异常之后的代码也可以执行)

try{
可能发生异常的代码
}catch(异常类型 变量名){
    发生异常后的代码
}
注意:
    1.发生异常后 try中异常下面的代码不执行 会看一下 catch能否捕获发生的异常

    2.当发生了不能捕获的异常 结束程序

    3.捕获多个异常
       3.1 使用 | 连接  异常类型1 | 异常类型2|...  变量名
       3.2 多重catch 将大的范围的异常写到后面(否则小范围的异常将不会被触发)
    4.try中声明的变量 只能在try中使用 其他位置想要使用 要进行作用域提升

Throwable
    a.printStackTrace();答疑异常的堆栈信息
    a.getMessage();获取异常的原因

 

public static void main(String[] args) {

        try {
            int[] arr = {10, 20};
            System.out.println("11111");
            int i = 10/0;
            // System.out.println(arr[12]);
            System.out.println("33333");
        } catch (ArrayIndexOutOfBoundsException  a) {

            a.printStackTrace();
            String message = a.getMessage();
            System.out.println("message = " + message);
        }catch (ArithmeticException a){
            a.printStackTrace();
            String message = a.getMessage();
            System.out.println("message = " + message);
        }catch (Exception e){

        }

        System.out.println("Game Over");
    }

finally测试

try{}catch(){}finally:
finally: 无论是否发生异常都有执行的代码

如果不想要执行finall里面的内容:
        System.exit(0); 退出jvm

public static void main(String[] args) {

        try {
            int[] arr = {10, 20};
            System.out.println("11111");
            int i = 10/2;
         //    System.out.println(arr[12]);

            System.out.println("33333");
          //  return;

            System.exit(0);

        } catch (ArithmeticException e){
            e.printStackTrace();
        }finally {
            System.out.println("Game Over");
        }
    }

throw与throws

throws  vs throw
    1.位置不同
        throws:方法的声明处
        throw:方法内
    2.数量不同
       throws 后面可以有多个异常【类型】
       throw 后只能有一个异常对象

    3.作用不同
        throw 手动抛出异常对象
        throws 通知方法调用者 调用本方法可能出现的问题

 注意:
    1.如果抛出的是运行时异常  方法声明处可以不用声明
    2.如果抛出的是编译时异常 且没有进行处理  那么方法声明处 必须 throws 声明
    3.只要是声明了编译时异常 一旦调用 必须处理

 

public class Test {
    public static void main(String[] args) {

        try {
            method1();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private static void method1() throws ArrayIndexOutOfBoundsException, ArithmeticException, FileNotFoundException {

            if(3>2){
                throw new ArrayIndexOutOfBoundsException();
            }
            if(3<4){
                throw new ArithmeticException("算数异常");
            }
            if(4>5){
                throw new NullPointerException();
            }

            if(6>8){
                throw new FileNotFoundException();
            }


    }
}

 finally和reeturn

public class FinallyReturn {

    public static void main(String[] args) {


        int num = method();

        System.out.println("num = " + num);

    }

    private static int method() {

        int num = 90;
        try {
            int[] arr = {10, 20};
            System.out.println(arr[20]);
            return 30;
        } catch (Exception e) {
            e.printStackTrace();
            return 40;
        } finally {
            return 50;
        }
    }
}

 

 

public class FinallyReturn1 {

    public static void main(String[] args) {
        int num = method();
        System.out.println("num = " + num);
    }
    private static int method() {
        int num = 90;
        try {
            int[] arr = {10, 20};
            System.out.println(arr[20]);
            return num;
        } catch (Exception e) {
            e.printStackTrace();
            num = 70;
            return num;//临时变量 记录好 即将返回的值

        } finally {
            num = 60;
          //  return num;
        }
    }
}

 方法重写与异常

子类不能抛出比父类更大的异常,这句话有bug

应该是  编译时异常  子类不能抛出比父类更大的异常

             运行时异常无所谓

RuntimeException和IOException都继承于Exception,Exception属于编译时异常,因为编译时一场更加严格。范围更大。

 

 

子类重写父类方法时
    1.权限修饰符 子类不能比父类更加严格 >=父类的访问权限

    2.返回值类型
            父类方法的返回值类型是 基本数据类型 子类重写时 要与父类一致
            父类方法的返回值类型是 引用数据类型 子类重写时 可以与父类一致 也可以是 父类返回值类型的子类

    3.方法名 形参列表 必须与父类方法一致

    4.异常
        如果父类抛出的是运行时异常 那么此类无所谓
        如果父类抛出的是编译时异常 那么子类不能抛出比父类更大的异常

注意:
    Exception 是编译时异常

public class Person {

    public void show() throws NullPointerException {


    }

    public void method() throws FileNotFoundException {

    }
}

class Son extends Person {

    @Override
    public void method() throws FileNotFoundException {

    }

    @Override
    public void show()  {

    }
}

 自定义异常:

如何实现自定义异常?
    1.新建一个类 AgeException

    2.此类继承一个系统异常类型
        2.1 如果希望是运行时异常 就继承运行时异常类
        2.2 如果希望是编译时异常 就继承编译时异常类

    3.写俩构造器
       无参
       有参

public class Person {
    private  String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        setAge(age);
    }

    public Person() {
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {

        if (age < 150){
            this.age = age;
        }else {

        throw new AgeException("您输入的年龄不合法");
        }

    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class AgeException extends RuntimeException {
    public AgeException() {
    }

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值