Java - 错误与异常 July 19,2019

异常与错误

 

在Java中有一个定义好的规则Throwable(可以抛出的)

Error错误

  通常是一些物理性的,JVM虚拟机本身出现的问题,程序指令是处理不了的

Exception

  通常是一种人为规定的不正常的现象,通常是规定的程序指令产生看一些不符合规范的事情

 

                Throwable

  Error(错误)                        Exception(异常)

(1)StackOverflowError                 RuntimeException(运行时异常)      IOException

(2)OutOfMemoryError                 

 

一、异常的分支体系:

运行时异常(非检查异常)

  Error和RuntimeException都算作运行时异常,javac编译的时候不会提示和发现的,在程序编写的时候不要求必须处理,我们可以添加处理手段(try   throws)

  1.InputMismatchException           输入不匹配  

        Scanner input = new Scanner(System.in);
        int value = input.nextInt();//应输入int类型,若输出其他类型则出现此异常   

 

 2.NumberFormatException       数字格式化

        int a = Integer.parseInt("123.00");//123.00不是int类型的
        System.out.println(a);

 

   3.NegativeArraySizeException       数组长度负数

int [] a = new int[-2];

 

   4.ArrayIndexOutOfBoundsException  数组索引越界

        int [] a = new int[5];
        System.out.println(a[7]);

 

   5.NullPointerException       空指针异常 

        int [] a = null;
        System.out.println(a[2]);
     int [][] array = new int[2][];
     System.out.println(array[1][0]);

 

   6.ArthmeticException       数字异常

        System.out.println(1.0/0);//输出Infinity
        System.out.println(1/0);//异常

 

 7.ClassCastException     造型异常

        Person p = new Teacher();
    Student s = (Student)p;   //强制向下造型       

 

    8.StringIndexOutOfBoundsException   字符串越界

        String a = "abcd";
        System.out.println(a.charAt(5));//超过字符串长度

 

    9.IndexOutOfBoundsException  集合越界 

        ArrayList  list = new ArrayList();
        list.add(1);
        list.add(2);
        System.out.println(list.get(5));//IndexOutOfBoundsException

 

 10.ILLegalArgumentException           非法参数异常

ArrayList  list = new ArrayList(-1);

 

编译时异常(检查异常)

  除了Error和RuntimeException以外其他的异常

  javac编译的时候(小红线下标的),强制要求我们必须为这样的异常做处理(try或者throws)

  因为这样的异常在程序运行过程中极有可能产生问题,异常产生后后续的所有执行就停止了

  1.InterruptException

 

//Thread.sleep(5000);//如果只写此行代码 则会出现编译异常
        
        //正确写法
        try{
            Thread.sleep(5000);
         }catch(Exception e){

            } 

 

 

二、添加处理异常的手段

1.try{}catch(){}[ finally{} ]

  1.try不能单独的出现
   2.后面必须添加catch或finally
   3.catch有一组括号 () 目的是为了捕获某一种异常
   4.catch可以有很多个存在
      捕获的异常之间没有任何的继承关系
      捕获的异常需要从小到大进行捕获

 public static void main(String[] args) {
        System.out.println("代码开始执行");
        try {
            int[] array = new int[2];
            System.out.println(array[3]);//索引越界,直接捕获
            System.out.println("try代码执行完毕");//此行不执行
        } catch (NegativeArraySizeException e) {//小的
            System.out.println("捕获到了数组长度异常");//应该是索引越界,所以这个不会捕获
        } catch (Exception e){   //若放在其他异常之前 ,则只执行这个异常捕获,其他异常不捕获
            System.out.println("父类捕获到了其他异常");
        }finally{ //总会执行
            System.out.println("finally执行了");
        }
        System.out.println("--end--");
    }

输出结果:
代码开始执行
父类捕获到了其他异常
finally执行了
--end--

  5.finally不是必须存在的

        若存在finally结构  则必须执行

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

        System.out.println("代码开始执行");
        try {
            int[] array = new int[2];
            System.out.println(array[3]);//索引越界,直接捕获
            System.out.println(array[-1]);

            System.out.println("try代码执行完毕");//此行不执行
        } catch (ArrayIndexOutOfBoundsException e) {//小的
            System.out.println("捕获到了数组索引越界异常");
        } catch (NegativeArraySizeException e) {//小的
            System.out.println("捕获到了数组长度异常");
        } catch (Exception e){   //最大的异常 , 若放在其他异常之前 ,则只执行这个异常捕获,其他异常不捕获
            System.out.println("父类捕获");
        }finally{ //总会执行
            System.out.println("finally执行了");
        }
        System.out.println("--end--");

    }
}

执行结果:
代码开始执行
捕获到了数组索引越界异常
finally执行了
--end--

 引申一个小问题:   final   finally  finalize区别:

       final  特征修饰符  修饰变量 属性 方法 类
          修饰变量 基本类型 值不能改变 引用类型 地址不能改变(如果变量没有初值 给一次机会赋值)
          修饰属性 特点与修饰变量类似 (要求必须给属性赋初始值 否则编译报错)
          修饰方法 不能被子类重写
          修饰类    不能被其他的子类继承
       finally 处理异常手段的一部分
          try{}catch(){}后面的一个部分
          这个部分可有可无  如果有只能含有一份 且必须执行
       finalize 是Object类中的一个protected方法
          对象没有任何引用指向的时候 -- 会被GC回收
          当对象回收的时候 默认调用finalize方法
          若想要看到对象回收的效果  可以重写 public void finalize(){}
   6.处理异常放在方法内部 可能还会有小问题
      如果在方法内部含有返回值
      不管返回值return关键字在哪里   finally一定会执行完毕
      返回值的具体结果   看情况

    public String testException(){
        System.out.println("代码开始执行");
        try {
            int[] array = new int[2];
            System.out.println(array[3]);//索引越界,直接捕获
            return "try代码执行完毕返回"; //如果无异常 则执行此行return
        } catch (ArrayIndexOutOfBoundsException e) {//小的
            System.out.println("捕获到了数组索引越界异常");
        } finally{ //无论return放在那 , finally也会执行
            System.out.println("finally执行了");
        }
        return "--end--";
    }

    public static void main(String[] args) {
        TestThrowable testThrowable = new TestThrowable();
         String value = testThrowable.testException();
        System.out.println(value);
}
输出结果:
代码开始执行
捕获到了数组索引越界异常
finally执行了
--end--

 

2.throws抛出
   1.异常只能在方法上抛出  属性是不能处理异常的
   2.方法  构造
   3.方法可以抛出不止一个异常  通过,隔开
   4.抛出的异常与多个catch类似  要么没关系 要么先抛出小异常

    public String test() throws NullPointerException,ArrayIndexOutOfBoundsException{
        String string =null;
        string.length();
        return "返回值";
    }

    public static void main(String[] args) {
        TestThrowable testThrowable = new TestThrowable();
        try {
            testThrowable.test();//谁调用方法 抛给谁
        }catch (Exception e){
            System.out.println("捕获到了异常");
        }
}
输出结果:
捕获到了异常

 

三、 我们也可以自己创建异常----自定义异常
 1.自己描述一个异常的类
 2.让我们自己的类继承
    如果继承是RuntimeException---->运行时异常(不需要必须添加处理手段)
    如果继承是Exception-------------->编译时异常(必须添加处理手段)
 3.创建一个当前自定义异常类的对象
    通过throw关键字  主动产生异常
 4.当我们设计描述的方法(事情)  之前没有相关的异常能描述我的问题Box
    这个时候才会利用自定义异常来描述

public class TestThrowable {
    //来设计一个方法 测试自定义异常的使用
    public void testMyException(){
        System.out.println("测试自定义异常的方法执行啦");
        if(3>2){//若满足某个条件
            throw new MyException();
        }
    }

     public static void main(String[] args) {
        TestThrowable testThrowable = new TestThrowable();
        testThrowable.testMyException();
    }

}

public class MyException extends RuntimeException{
}
public class TestThrowable {
 //来设计一个方法 测试自定义异常的使用
    public void testMyException() throws MyException{
        System.out.println("测试自定义异常的方法执行啦");
        if(3>2){//若满足某个条件
            throw new MyException("说明一下异常的具体问题");
        }
    }

    public static void main(String[] args) {
        TestThrowable testThrowable = new TestThrowable();
        try {
            testThrowable.testMyException();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

public class MyException extends Exception{
    public MyException(){}
    public MyException(String msg){
        super(msg);
    }
}

输出结果:
测试自定义异常的方法执行啦
test_throwable.MyException: 说明一下异常的具体问题

 

posted @ 2019-07-19 11:30  亿贫如洗杨道长  阅读(24)  评论(0编辑  收藏  举报