29Java的异常机制学习(存疑)

Java的异常这块有几位优秀的博主已经介绍的很详细了,我这里就记录一下我的实现过程和学习过程中遇到的问题。

异常(Exception)

java的异常是用于处理程序中异常或错误的一种机制。

回顾:

IDE一般指集成开发环境。集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具.

JDK: Java Development Kit java开发工具箱

JRE:Java Runtime Environment java执行环境

JVM:Java Virtual Machine Java虚拟机

在这里插入图片描述

异常分类:

在这里插入图片描述

异常处理办法一:使用try…catch…捕获

java是采取面向对象的方式来处理异常。处理过程是:

扫描二维码关注公众号,回复: 13120453 查看本文章
  1. 抛出异常: 在执行一个方法时,如果发生异常,则这个方法生成该异常的一个对象,停止当前执行路径,并把异常对象交给JRE(Java Runtime Environment)。
  2. 捕获异常: JRE得到该异常后,寻找响应的代码来处理该异常,JRE在方法的调用栈中查找,从生成异常方法开始回溯,直到找到响应的异常处理代码为止。

在这里插入图片描述

左边程序的执行顺序:

try =》语句1 =》语句2 =》finally =》语句4 (不执行catch里面的语句3).

右边的程序执行顺序:

try =》语句1 =》语句2(遇到异常)=》(不执行语句3)catch =》语句4 =》finally =》语句5.

package oop.oopdemo.testexception;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * 测试异常语句
 *
 * @author 发达的范
 * @date 2020/10/28
 */
public class testException {
    
    
    public static void main(String[] args) {
    
    
        FileReader fileReader = null;
        //Checked Exception是可以预测的,所以要捕获异常进行处理
        try {
    
    
            fileReader = new FileReader("E:\\hello.txt");
            //Reads a single character,其中read()方法:public int read() throws java.io.IOException
            char c = (char) fileReader.read();
            char c1 = (char) fileReader.read();//Reads a single character.
            System.out.println("" + c + c1);//转成字符串进行输出
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    //应该把父类的catch语句放在子类后面
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                if (fileReader != null) {
    
    
                    fileReader.close();
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

try {} catch{} 语句可以使用快捷键生成,Ctrl+Alt+T,或者点击Codes -> Surround With… -> 选择相应的操作即可

try ,catch,finally的执行顺序:

  1. 执行try…catch…,给返回值赋值
  2. 执行finally
  3. 执行return
package oop.oopdemo.testexception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 测试异常捕获语句的执行顺序
 *
 * @Author 发达的范
 * @Date 2020/10/28
 * @Time 14:09
 */

public class TestExecutiveOrder {
    
    
    public static void main(String[] args) {
    
    
        String string = new TestExecutiveOrder().openFile();
        System.out.println(string);
    }

    String openFile() {
    
    
        try {
    
    
            System.out.println("aaa");
            FileInputStream fis = new FileInputStream("E:\\(A)PostgraduateFlies\\Javalearing\\abc.txt");
            int a = fis.read();
            System.out.println("bbb");
            return "step1";
        } catch (FileNotFoundException e) {
    
    
            System.out.println("catching!");
            e.printStackTrace();
            return "step2";
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return "step3";
        }finally {
    
    
            System.out.println("finally!");
        }
    }
}

运行结果:在这里插入图片描述

从执行结果来看:在没有异常时,首先执行try,然后执行 finally,最后执行try中的return语句。

如果try中的文件操作代码发生异常,则执行结果为:在这里插入图片描述

可见,首先进入try按顺序执行,发生异常后,异常语句后面的语句不再执行,直接执行这个异常的捕获语句catch语句,然后再执行finally语句,最后执行return语句。且无论有没有异常出现,都会执行finally语句。


异常处理办法二:声明异常:throws语句

使用throws就是把当前代码的异常自己不处理,抛给调用它的对象进行处理,抛出去几个异常,它的上层就要处理几个异常。

package oop.oopdemo.testexception;

/**
 * 测试异常的抛出问题
 *
 * @author 发达的范
 * @date 2020/10/28
 */
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class TestThrows {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            String string = new TestThrows().openFile();
            System.out.println(string);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
	//自己不处理异常,抛出去,谁调用谁处理,抛给上层
    String openFile() throws FileNotFoundException, IOException {
    
    
        System.out.println("aaa");
        FileInputStream fis = new FileInputStream("E:\\(A)PostgraduateFlies\\Javalearing\\abc.txt");
        char c = (char) fis.read();
        System.out.println("bbb");
        return "step1";
    }
}

注:main方法里面仍可以继续向上抛throws,但是不推荐。

方法重写中声明异常的原则

  • 子类声明的异常范围不能超过父类声明的范围。
    • 父类没有声明的异常,子类也不能声明
    • 不可抛出原有方法抛出异常可的父类或上层类
    • 子类抛出的异常类型数目不可比原有方法抛出的还多(不是指个数)
package oop.oopdemo.testexception;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;

/**
 * 测试继承之后异常的抛出问题
 *
 * @author 发达的范
 * @date 2020/10/28
 */
class TestExtendsException {
    
    
    public void method()throws IOException {
    
     }
}


class B extends TestExtendsException {
    
    
    public void method() throws FileNotFoundException {
    
     }
}

class C extends TestExtendsException {
    
    
    public void method() {
    
     }
}

class D extends TestExtendsException {
    
    
    public void method() throws Exception {
    
        }//超出父类异常的范围
}

class E extends TestExtendsException {
    
    
    public void method() throws IOException, FileNotFoundException {
    
    
    }
}

class F extends TestExtendsException {
    
    
    public void method() throws IOException, ArithmeticException {
    
    //父类结合RuntimeException可以
    }
}

class G extends TestExtendsException {
    
    
    public void method() throws IOException, ParseException {
    
     }//父类结合非RuntimeException不可以,超范围
}

至于“ 父类结合RuntimeException可以,父类结合非RuntimeException不可以,超范围”这个问题我还是没搞明白

JDK1.8API中显示:

在这里插入图片描述

由此可见,ArithmeticException类和ParseException类都不是IOException类的子类,它们的区别就是:ParseException类与IOException类是平级的,而ArithmeticException类比它们低了一级,我现在对这个疑问的猜想是:子类方法同时throws IOException, ParseException导致抛出的异常类型比父类方法抛出的类型多了。这个问题先留着,待以后解决!

异常处理办法三:手动抛出异常,throw语句(不是throws)

  • Java异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要手工创建并抛出。
  • 在捕获一个异常前,必须有一段代码先生成异常对象并把它抛出。这个过程我们可以手工做,也可以由JRE来实现,但是他们调用的都是throw子句。
  • 对于一个已经存在的异常类,抛出该类异常对象过程如下:
    1. 找到一个合适的异常类;
    2. 创建一个该类的对象;
    3. 将对象抛出。
package oop.oopdemo.testexception;

import java.io.File;
import java.io.FileNotFoundException;

/**
 * 测试手动抛出异常
 * 
 * @Author 发达的范
 * @Date 2020/10/28
 */
public class TestThrow {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("c:/tt. txt");
        if (!f.exists()) {
    
    
            try {
    
    
                throw new FileNotFoundException("File can't be found!");//手动 new 一个异常类的对象
            } catch (FileNotFoundException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

自定义异常

package oop.oopdemo.testexception;

/**
 * 测试使用自定义异常
 * 
 * @Author 发达的范
 * @Date 2020/10/28
 */
public class MyException extends Exception {
    
    
    public MyException() {
    
    

    }

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


class TestMyException {
    
    
    void test() throws MyException {
    
    

    }

    public static void main(String[] args) {
    
    
        try {
    
    
            new TestMyException().test();
        } catch (MyException e) {
    
    
            e.printStackTrace();
        }
    }
}

使用异常机制的建议:

  • 要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下。
    • 比如:登录界面的密码校验,不需要进行一系列的异常校验(密码位数不对,账号类型错误等),这样反而把问题变复杂了,直接使用if…else…语句就可以解决
  • 处理异常不可以代替简单测试-—-只在异常情况下使用异常机制
  • 不要进行小粒度的异常处理-—-应该将整个任务包装在一个Try语句块中
  • 异常往往在高层处理。

猜你喜欢

转载自blog.csdn.net/fada_is_in_the_way/article/details/109338423
今日推荐