JavaSE学习(Day09)【异常】

文章目录

异常

1、什么是异常?,java提供异常处理机制有什么用?
    程序执行过程中,发生了不正常的情况,这种不正常的情况就是:异常
    Java把异常信息打印到输出的控制台 (JVM打印的),供程序员参考,程序员看到后,会进行修改
    让程序更加健壮
2、异常在java中以类的形式存在,每一个异常类都可以创建异常对象
3、异常在生活中的体现:
    火灾(异常类):
        小明家着火了(异常对象)
        小红家着火了(异常对象)
        小黑家着火了(异常对象)


1、Java的异常处理机制
    1.1异常在Java中以类和对象的形式存在,异常的继承结构:
    Object
    Object下有Throwable(可抛出的)
    Throwable下有两个分支:
        Error(不可处理,直接退出JVM)和Exception(可处理的)
    Exception下有两个分支:
      Exception的直接子类:编译时异常(要求程序员在编写程序阶段就必须预先对这些异常进行处理)
      RuntimeException:运行时异常(在编写程序阶段程序员可以预先处理,也可以不管)

1.2、编译时异常和运行时异常,都发生在运行阶段。编译阶段异常是不会发生的。
编译时异常因为什么得名?
    因为编译时异常必须在编译(编写)阶段预先处理,如果不处理编译器报错,因此得名。
    所有异常都是在运行阶段发生的。因为只有程序运行阶段才可以new对象。
    因为异常的发生就是new异常对象。

 1.3、 编译时异常和运行时异常的区别?

    编译时异常一般发生的概率比较高。
        举个例子:
         看见外面下大雨,出门前就会预料到:
         不打伞可能会生病(一种异常),所以拿一把伞
         ”拿伞“就是对”生病“异常发生之前的一种处理方式

         对于一些发生概率较高的异常,需要在运行之前对其进行预处理。
    运行时异常一般发生的概率比较低。
        举个例子:
        小明走在大街上,可能被天上的飞机轮子砸到(异常)。
        在出门之前没有必要提前对这种发生概率低的异常进行预处理。
        如果处理这种异常,活得很累
 1.4、编译时异常还有其他的名字:
    受检异常
    受控异常
 1.5、运行时异常还有其他的名字:
    未受检异常
    非受控异常
 1.6、Java语言中对异常的处理包括两种方式:
    第一种方式:在方法声明的位置上,使用throws关键字,抛给上一级。
    第二种方式:使用try...catch语句进行异常的捕捉。
                可以有多个catch(从小到大)
      什么时候用throws?
            当需要将异常上报的时候用throws
  1.8、注意:
    Java中异常发生以后如果一直上抛,最终抛给了main方法,main方法继续
    向上抛,抛给了调用者JVM,JVM知道了这个异常发生,只有一种结果,终止
    java程序的执行。
  1.9、异常对象有两个重要的方法:
     获取异常简单的描述信息:
        String msg = exception.getMessage();
     打印异常追踪的堆栈信息:
        exception.printStackTrace();

java.lang.Throwable类是 Java语言中所有错误或异常的父类

Exception:编译期异常,进行编译(写代码)java程序中出现的问题

RuntimeException:运行期异常,java程序运行过程中出现的问题(我们不用处理,默认交给JVM处理)
异常就相当于程序得了小毛病(感冒),把异常处理掉,程序可以继续执行

Error:错误

错误就相当于程序的了一个无法治疗的毛病,必须修改源代码,程序才能继续执行

throw关键字

作用:

可以使用throw关键字在指定的方法中抛出指定的异常

使用格式

throw new XXXException("异常产生的原因");

注意:

1、throw关键字必须写在方法的内部
2、throw关键字后边new的对象必须是Exception或者Exception的子类对象
3、throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
    throw关键字后面创建的是RuntimeException或者是其子类,我们可以不处理,默认交给JVM处理
    throw关键字后面创建的是编译异常(写代码时报错),我们必须处理这个异常,要么throws要么try...catch
public class DemoThrow {
    public static void main(String[] args) {
        int arr[]={1,2,3,4,5};
        getElement(arr,3);

//        int arr1[] = null;
//        getElement(arr1,2);//NullPointerException: 传递的数组值为null

        int arr2[] = {1,2,3,4};
        getElement(arr2,6);//ArrayIndexOutOfBoundsException: 索引越界
    }
    //定义一个方法,获取数组指定索引的元素
    public static int getElement(int[] arr,int index){
        //我们要对传递过来的参数--数组,进行合法性校验
        //如果数组arr的值是null,我们抛出空指针异常
        //告诉调用者“传递的数组值为null”
        if(arr == null){
            //NullPointerException是运行期异常,我们不用处理,交给JVM
            throw new NullPointerException("传递的数组值为null");
        }

        //我们可以对传递过来的参数--index进行合理性校验
        //如果index的范围不在数组的索引范围中,我们就抛出数组索引越界异
        //告诉调用者“索引越界”
        if(index<0 || index>arr.length-1){
            //ArrayIndexOutOfBoundsException是运行期异常
            throw new ArrayIndexOutOfBoundsException("索引越界");
        }
        int ele = arr[index];
        System.out.println(ele);
        return 0;
    }
}

throws 抛出异常给JVM,一旦出现异常就在控制台打印异常信息,并且不会继续执行下面的代码了

public class DemoThrows {
    public static void main(String[] args) throws ParseException {
        //Exception:编译期异常
        SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd");//用来格式化日期
        Date date = sdf.parse("1999-04-29");//把字符串格式的日期,解析为Date格式的日期
        System.out.println(date);//Thu Apr 29 00:00:00 CST 1999
        Date date1 = sdf.parse("1999-0429");
        System.out.println(date1);//Exception in thread "main" java.text.ParseException: Unparseable date: "1999-0429"
        System.out.println("后续");//无法执行
    }
}

try…catch处理异常,遇到异常会在控制台打印出异常信息,并且会继续执行后面的代码

public class DemoTry {
    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd");

        Date date = null;
        try {
            date = sdf.parse("1999-0429");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println(date);//java.text.ParseException: Unparseable date: "1999-0429"  null
        System.out.println("后续");//后续(执行)
    }
}

异常对象有两个重要的方法:

  获取异常简单的描述信息:
  String msg = exception.getMessage();
 打印异常追踪的堆栈信息:
  exception.printStackTrace();
public class Demo02 {
    public static void main(String[] args) {
        NullPointerException e = new NullPointerException("空指针异常");

        //获取异常简单信息描述:这个信息实际上就是构造方法上面string参数
        String msg = e.getMessage();
        System.out.println(msg);//空指针异常

        //打印异常堆栈信息
        //java后台打印异常堆栈信息,采用了异步线程的方式
        e.printStackTrace();//java.lang.NullPointerException: 空指针异常	at cf.daunzifan.JavaTest.Day07.Exception.Demo02.main(Demo02.java:9)
    }
}

关于try…catch中的finally子句

1、在finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块中的代码出现了异常。
2、finally语句通常使用在哪些情况:
    通常在finally语句块中完成资源的释放/关闭。
    因为finally中的代码有保障
    即使try中出现异常,也会执行
public class Demo03 {
    public static void main(String[] args) {
        /*
        try不能单独使用
        try finally可以联合使用(可以没catch)
        下面代码的执行顺序:
            先执行try...
            再执行fin...
            最后执行return

         */
        try{
            System.out.println("try..");
            return;
        }finally {
            System.out.println("fin....");
        }//try..//fin....
    }
}

final finally finalize的区别?

public class Demo05 {
    public static void main(String[] args) {
        final int I = 100;
        //final是一个关键字,表示最终的
        //final修饰的类无法继承
        //final修饰的方法无法覆盖
        //final修饰的变量无法重新赋值


        //finally也是一个关键字,和try联合使用,使用在异常处理机制中

        //finalize()是Object类中的一个方法,是标识符
        //这个方法是由垃圾回收器GC负责调用的
    }
}

自定义异常

两步:
        1、编写一个类继承Exception或者RuntimeException
        2、提供两个构造方法,一个无参数,一个带有String参数的。
public class MyException extends Exception {//编译时异常


    public MyException() {
    }

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

/*
public class MyException extends RuntimeException {//运行时异常

}
*/

public class MyExceptionTest {
    public static void main(String[] args) {
        //创建异常对象(只new了异常对象,并没有手动抛出(throw e))
        MyException e = new MyException("自己的异常");
        //throw e;//手动抛出
        //合并写法 
        //throw e = new MyException("自己的异常");

        //打印异常堆栈信息
        e.printStackTrace();//cf.daunzifan.JavaTest.Day07.Exception.MyException: 自己的异常

        //获取异常简单描述信息
        String msg = e.getMessage();
        System.out.println(msg);//自己的异常
    }
}

异常原理解析

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值