首页 > 编程语言 > 详细

Java异常

时间:2020-09-15 22:55:31      阅读:69      评论:0      收藏:0      [点我收藏+]

Java异常

ExceptionTest01——什么是异常,java提供异常处理机制有什么用?

  1. 什么是异常,java提供异常处理机制有什么用?

    什么是异常:程序执行过程中的不正常情况。

    异常的作用:帮助程序员查找错误,增强程序的健壮性。

    例如:

    Exception in thread "main" java.lang.ArithmeticException: / by zero
    这个信息被我们称为:异常信息。这个信息是JVM打印的。

  2. 以下实例是一个除数为0的数学算术异常。

public class ExceptionTest01 {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        // 实际上JVM在执行到此处的时候,会new异常对象:new ArithmeticException("/ by zero");
        // 并且JVM将new的异常对象抛出,打印输出信息到控制台了。
        int c = a / b;
        System.out.println(a + "/" + b + "=" + c);
    }
}

ExceptionTest02——异常的存在形式

java语言中异常是以什么形式存在的呢?

  1. 异常在java中以类的形式存在,每一个异常类都可以创建异常对象。

  2. 异常对应的现实生活中是怎样的?

    火灾(异常类):
    2008年8月8日,小明家着火了(异常对象)
    2008年8月9日,小刚家着火了(异常对象)
    2008年9月8日,小红家着火了(异常对象)

    类是:模板。
    对象是:实际存在的个体。

    钱包丢了(异常类):
    2008年1月8日,小明的钱包丢了(异常对象)
    2008年1月9日,小芳的钱包丢了(异常对象)
    ....

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

        // 通过“异常类”实例化“异常对象”
        NumberFormatException nfe = new NumberFormatException("数字格式化异常!");

        // java.lang.NumberFormatException: 数字格式化异常!
        System.out.println(nfe);

        // 通过“异常类”创建“异常对象”
        NullPointerException npe = new NullPointerException("空指针异常发生了!");

        //java.lang.NullPointerException: 空指针异常发生了!
        System.out.println(npe);
    }
}

ExceptionTest03——在编写程序阶段不需要对运行时异常进行预先的处理

public class ExceptionTest03 {
    public static void main(String[] args) {
        /*
        程序执行到此处发生了ArithmeticException异常,
        底层new了一个ArithmeticException异常对象,
        然后抛出了,由于是main方法调用了100 / 0,
        所以这个异常ArithmeticException抛给了main方法,
        main方法没有处理,将这个异常自动抛给了JVM。
        JVM最终终止程序的执行。

        ArithmeticException 继承 RuntimeException,属于运行时异常。
        在编写程序阶段不需要对这种异常进行预先的处理。
         */
        System.out.println(100 / 0);

        // 这里的HelloWorld没有输出,没有执行。
        System.out.println("Hello World!");
    }
}

ExceptionTest04——编译时异常

/*
以下代码报错的原因是什么?
    因为doSome()方法声明位置上使用了:throws ClassNotFoundException
    而ClassNotFoundException是编译时异常。必须编写代码时处理,没有处理
    编译器报错。
 */
public class ExceptionTest04 {
    public static void main(String[] args) {
        // main方法中调用doSome()方法
        // 因为doSome()方法声明位置上有:throws ClassNotFoundException
        // 我们在调用doSome()方法的时候必须对这种异常进行预先的处理。
        // 如果不处理,编译器就报错。
        //编译器报错信息: Unhandled exception: java.lang.ClassNotFoundException
        //doSome();
    }

    /**
     * doSome方法在方法声明的位置上使用了:throws ClassNotFoundException
     * 这个代码表示doSome()方法在执行过程中,有可能会出现ClassNotFoundException异常。
     * 叫做类没找到异常。这个异常直接父类是:Exception,所以ClassNotFoundException属于编译时异常。
     * @throws ClassNotFoundException
     */
    public static void doSome() throws ClassNotFoundException{
        System.out.println("doSome!!!!");
    }

}

ExceptionTest05——处理异常的两种方式

第一种处理方式:在方法声明的位置上继续使用:throws,来完成异常的继续上抛。抛给调用者。

上抛类似于推卸责任。(继续把异常传递给调用者。)

第二种处理方式:try..catch进行捕捉。

捕捉等于把异常拦下了,异常真正的解决了。(调用者是不知道的。)

public class ExceptionTest05 {
    // 第一种处理方式:在方法声明的位置上继续使用:throws,来完成异常的继续上抛。抛给调用者。
    // 上抛类似于推卸责任。(继续把异常传递给调用者。)
    /*
    public static void main(String[] args) throws ClassNotFoundException {
        doSome();
    }
     */

    // 第二种处理方式:try..catch进行捕捉。
    // 捕捉等于把异常拦下了,异常真正的解决了。(调用者是不知道的。)
    public static void main(String[] args) {
        try {
            doSome();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void doSome() throws ClassNotFoundException{
        System.out.println("doSome!!!!");
    }
}

ExceptionTest06——异常捕捉和上报的联合使用

/*
处理异常的第一种方式:
    在方法声明的位置上使用throws关键字抛出,谁调用我这个方法,我就抛给谁。抛给调用者来处理。
    这种处理异常的态度:上报。

处理异常的第二种方式:
    使用try..catch语句对异常进行捕捉。
    这个异常不会上报,自己把这个事儿处理了。
    异常抛到此处为止,不再上抛了。

注意:
    只要异常没有捕捉,采用上报的方式,此方法的后续代码不会执行。
    另外需要注意,try语句块中的某一行出现异常,该行后面的代码不会执行。
    try..catch捕捉异常之后,后续代码可以执行。

在以后的开发中,处理编译时异常,应该上报还是捕捉呢,怎么选?
    如果希望调用者来处理,选择throws上报。
    其它情况使用捕捉的方式。
 */
public class ExceptionTest06 {
    // 一般不建议在main方法上使用throws,因为这个异常如果真正的发生了,一定会抛给JVM。JVM只有终止。
    // 异常处理机制的作用就是增强程序的健壮性。怎么能做到,异常发生了也不影响程序的执行。所以
    // 一般main方法中的异常建议使用try..catch进行捕捉。main就不要继续上抛了。
    /*
    public static void main(String[] args) throws FileNotFoundException {
        System.out.println("main begin");
        m1();
        System.out.println("main over");
    }
     */
    public static void main(String[] args) {

        // 100 / 0这是算术异常,这个异常是运行时异常,你在编译阶段,可以处理,也可以不处理。编译器不管。
        //System.out.println(100 / 0); // 不处理编译器也不管
        // 你处理也可以。
        /*
        try {
            System.out.println(100 / 0);
        } catch(ArithmeticException e){
            System.out.println("算术异常了!!!!");
        }
         */

        System.out.println("main begin");
        try {
            // try尝试
            m1();
            // 以上代码出现异常,直接进入catch语句块中执行。
            System.out.println("hello world!");
        } catch (FileNotFoundException e){ // catch后面的好像一个方法的形参。
            // 这个分支中可以使用e引用,e引用保存的内存地址是那个new出来异常对象的内存地址。
            // catch是捕捉异常之后走的分支。
            // 在catch分支中干什么?处理异常。
            System.out.println("文件不存在,可能路径错误,也可能该文件被删除了!");
            System.out.println(e); //java.io.FileNotFoundException: D:\course\01-课\学习方法.txt (系统找不到指定的路径。)
        }

        // try..catch把异常抓住之后,这里的代码会继续执行。
        System.out.println("main over");
    }

    private static void m1() throws FileNotFoundException {
        System.out.println("m1 begin");
        m2();
        // 以上代码出异常,这里是无法执行的。
        System.out.println("m1 over");
    }

    // 抛别的不行,抛ClassCastException说明你还是没有对FileNotFoundException进行处理
    //private static void m2() throws ClassCastException{
    // 抛FileNotFoundException的父对象IOException,这样是可以的。因为IOException包括FileNotFoundException
    //private static void m2() throws IOException {
    // 这样也可以,因为Exception包括所有的异常。
    //private static void m2() throws Exception{
    // throws后面也可以写多个异常,可以使用逗号隔开。
    //private static void m2() throws ClassCastException, FileNotFoundException{
    private static void m2() throws FileNotFoundException {
        System.out.println("m2 begin");
        // 编译器报错原因是:m3()方法声明位置上有:throws FileNotFoundException
        // 我们在这里调用m3()没有对异常进行预处理,所以编译报错。
        // m3();

        m3();
        // 以上如果出现异常,这里是无法执行的!
        System.out.println("m2 over");
    }

    private static void m3() throws FileNotFoundException {
        // 调用SUN jdk中某个类的构造方法。
        // 这个类还没有接触过,后期IO流的时候就知道了。
        // 我们只是借助这个类学习一下异常处理机制。
        // 创建一个输入流对象,该流指向一个文件。
        /*
        编译报错的原因是什么?
            第一:这里调用了一个构造方法:FileInputStream(String name)
            第二:这个构造方法的声明位置上有:throws FileNotFoundException
            第三:通过类的继承结构看到:FileNotFoundException父类是IOException,IOException的父类是Exception,
            最终得知,FileNotFoundException是编译时异常。

            错误原因?编译时异常要求程序员编写程序阶段必须对它进行处理,不处理编译器就报错。
         */
        //new FileInputStream("D:\\course\\01-开课\\学习方法.txt");

        // 我们采用第一种处理方式:在方法声明的位置上使用throws继续上抛。
        // 一个方法体当中的代码出现异常之后,如果上报的话,此方法结束。
        new FileInputStream("D:\\course\\01-课\\学习方法.txt");

        System.out.println("如果以上代码出异常,这里会执行吗??????????????????不会!!!");
    }
}

ExceptionTest07——深入了解try...catch

  1. 如果抛出的时其他异常,那么在编译时仍会报错。

    //编译报错
    try {
        FileInputStream fis = new FileInputStream("D:\\JavaSE进阶讲义\\面向对象.pdf");
    } catch(NullPointerException e) {
    
    }
    
  2. 如果程序发生异常时,那么第一句输出语句不会执行,第二句在任何情况下都会执行。

    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("D:JavaSE进阶讲义\\面向对象.pdf");
            System.out.println("以上出现异常,这里无法执行!");
        } catch(FileNotFoundException e) {
            System.out.println("文件不存在!");
        }
        System.out.println("hello world!");
    }
    
  3. 可以抛出一个比发生异常范围大点的异常。

    try {
        FileInputStream fis = new FileInputStream("D:\\JavaSE进阶讲义\\面向对象.pdf");
    } catch(IOException e) { // 多态:IOException e = new FileNotFoundException();
        System.out.println("文件不存在!");
    }
    
    //能够捕获所有异常
    try {
        FileInputStream fis = new FileInputStream("D:\\JavaSE进阶讲义\\面向对象.pdf");
    } catch(IOException e) { // 多态:IOException e = new FileNotFoundException();
        System.out.println("文件不存在!");
    }
    
  4. 如果抛出不同类型的异常,建议精确的一个一个处理。这样有利于程序的调试。

    try {
        //创建输入流
        FileInputStream fis = new FileInputStream("D:\\JavaSE进阶讲义\\面向对象.pdf");
        //读文件
        fis.read();
    } catch(FileNotFoundException e) {
        System.out.println("文件不存在!");
    } catch(IOException e){
        System.out.println("读文件报错了!");
    }
    
  5. catch写多个的时候,从上到下,必须遵守从小到大。

    // 编译报错。
    try {
        //创建输入流
        FileInputStream fis = new FileInputStream("D:\\JavaSE进阶讲义\\面向对象.pdf");
        //读文件
        fis.read();
    } catch(IOException e){
        System.out.println("读文件报错了!");
    } catch(FileNotFoundException e) {
        System.out.println("文件不存在!");
    }
    
/*
深入try..catch
    1、catch后面的小括号中的类型可以是具体的异常类型,也可以是该异常类型的父类型。
    2、catch可以写多个。建议catch的时候,精确的一个一个处理。这样有利于程序的调试。
    3、catch写多个的时候,从上到下,必须遵守从小到大。
 */
public class ExceptionTest07 {
    public static void main(String[] args) {
        // JDK8的新特性!
        try {
            //创建输入流
            FileInputStream fis = new FileInputStream("D:\\curse\\02-JavaSE\\document\\JavaSE进阶讲义\\JavaSE进阶-01-面向对象.pdf");
            // 进行数学运算
            System.out.println(100 / 0); // 这个异常是运行时异常,编写程序时可以处理,也可以不处理。
        } catch(FileNotFoundException | ArithmeticException | NullPointerException e) {
            System.out.println("文件不存在?数学异常?空指针异常?都有可能!");
        }
    }
}

Java异常

原文:https://www.cnblogs.com/nieaojie625/p/13676100.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!