关于异常处理的知识整理

这篇博客详细介绍了Java中的异常处理机制,包括异常的定义、继承结构、处理方式以及异常对象的重要方法。异常作为程序执行中不正常的情况,通过类和对象的形式存在。Java提供异常处理机制以增强程序的健壮性,异常分为编译时异常和运行时异常。异常处理有两种方式:使用throws声明抛出异常,或者使用try...catch进行捕获。异常对象的getMessage()方法用于获取描述信息,printStackTrace()用于打印堆栈跟踪。

目录

1.什么是异常?

2.异常继承结构

3.异常结构继承图

 4.关于异常处理的两种方式:

5.异常对象有两个非常重要的方法


 

1.什么是异常?

程序在执行过程中不正常的情况称为异常,以类和对象的形势存在,可以通过异常类,创建和实例化异常对象。发生异常时JVM会new异常对象。

Java语言是很完善的语言,提供了异常处理机制,当程序在执行过程中出现异常而终止,java会把异常信息打印输出在控制台,以供参考。

存在的意义:增强java程序的健壮性。

2.异常继承结构

父类:java.lang.Throwable

子类:Error(错误类),Excepition(异常类)

Excepition有两个分支:

一个是异常的直接子类,被称为编译时异常,也叫做受检异常,要求程序员在编写程序的时候必须处理,如果不处理,编译器会报错。

另一个分支是RuntimeException(运行时异常),也叫做非受检异常,在编写程序时,程序员可以选择做预处理,也可以不管,不会影响程序的编译阶段。

3.异常结构继承图

 4.关于异常处理的两种方式:

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

       这种处理异常的态度:上报。

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

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

在以后的开发中,处理编译时异常,应该上报还是捕捉呢,怎么选?
    如果希望调用者来处理,选择throws上报。
    其它情况使用捕捉的方式。
 

public class ExceptionTest {
    // 一般不建议在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("如果以上代码出异常,这里会执行吗??????????????????不会!!!");
    }
}

5.异常对象有两个非常重要的方法

    获取异常简单的描述信息:
        String msg = exception.getMessage();

    打印异常追踪的堆栈信息:
        exception.printStackTrace(); 

 public static void main(String[] args) {
        // 这里只是为了测试getMessage()方法和printStackTrace()方法。
        // 这里只是new了异常对象,但是没有将异常对象抛出。JVM会认为这是一个普通的java对象。
        NullPointerException e = new NullPointerException("空指针异常fdsafdsafdsafds");

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

        // 打印异常堆栈信息
        // java后台打印异常堆栈追踪信息的时候,采用了异步线程的方式打印的。
        e.printStackTrace();

        for(int i = 0; i < 1000; i++){
            System.out.println("i = " + i);
        }

        System.out.println("Hello World!");
    }
}

<think>好的,我现在需要处理用户关于GESP考试大纲中异常处理知识点的问题。首先,用户明确提到想查找异常处理相关的知识点总结,并引用了三个参考内容。我需要先仔细查看这些引用,确定哪些部分与异常处理相关。 首先,引用[3]中明确提到四级考试内容包含“异常处理”[^3],这说明异常处理属于GESP四级考纲的一部分。其他引用[1]和[2]主要介绍GESP考试的整体情况和一级、四级的部分内容,但没有提到异常处理的具体细节。因此,我需要集中分析引用[3]中的相关信息,并结合自己的知识补充可能的考试内容。 接下来,我需要回忆C++中异常处理的基本知识点,通常包括try、catch、throw关键字的使用,异常处理的机制,以及可能涉及的注意事项,如异常传播、栈展开等。根据GESP四级的要求,可能不会涉及太复杂的部分,比如自定义异常类或标准异常体系,但基础的部分是必须的。 用户可能希望得到结构化的总结,比如分点列出知识点,并给出示例代码。同时,用户可能需要了解考试中可能出现的题型或考查方式,比如选择题或编程题中如何处理异常。 另外,需要确保回答符合用户提供的格式要求,如使用中文、正确使用LaTeX格式,生成相关问题等。特别是要检查LaTeX语法是否正确,比如行内公式用$...$,独立公式用$$...$$,并且正确引用标记。 可能还需要考虑用户的实际需求,他们可能是正在备考的学生,需要明确考试范围和重点,所以回答需要简洁明了,重点突出,避免冗余信息。同时,生成的相关问题应该与异常处理相关,帮助用户进一步巩固知识或扩展学习。 最后,要确保引用的正确性,引用[3]确实提到了异常处理,所以引用标记应正确添加在相关内容末尾。同时,示例代码需要用Python或C++?根据引用[3],四级同时涉及C++和Python,但用户的问题中引用[3]提到的是C++的结构体、指针等,而示例代码中可能以C++为主,但需要确认。根据用户提供的示例,之前的Python代码可能只是例子,而用户当前问题涉及C++,所以示例代码应该用C++的异常处理语法。 总结步骤: 1. 确定异常处理在GESP四级考纲中的位置。 2. 整理C++异常处理的核心知识点。 3. 结构化分点列出,包括语法、流程、注意事项。 4. 提供示例代码,使用C++语言。 5. 生成相关问题,如异常处理机制、应用场景、与其他错误处理方式的对比等。 6. 检查格式是否符合要求,引用正确,LaTeX无误。</think>根据GESP考纲四级要求,异常处理知识点总结如下: ### GESP四级异常处理核心知识点 1. **基本语法结构** - 使用`try`定义可能抛出异常的代码块 - 使用`catch`捕获并处理特定类型的异常 - 通过`throw`主动抛出异常对象 ```cpp try { if (error_condition) throw "Error Message"; } catch (const char* msg) { cout << "捕获异常:" << msg; } ``` 2. **异常处理流程** - 异常抛出后立即中断当前执行流 - 在调用栈中逆向查找匹配的`catch`块 - 未捕获的异常会导致程序终止 3. **多类型异常处理** - 可定义多个`catch`块处理不同类型异常 - 使用`catch(...)`捕获所有未指定类型的异常 ```cpp try { // 可能抛出多种异常的代码 } catch (int errCode) { // 处理整型异常 } catch (const std::exception& e) { // 处理标准异常 } catch (...) { // 处理其他所有异常 } ``` 4. **标准异常类**(C++特有) - `<stdexcept>`头文件包含常用异常类: - `runtime_error`:运行时错误 - `logic_error`:程序逻辑错误 - 派生类如`invalid_argument`、`out_of_range`等 5. **文件操作异常处理** - 文件读写时推荐结合异常处理: ```cpp #include <fstream> using namespace std; try { ifstream file("data.txt"); if (!file) throw runtime_error("文件打开失败"); } catch (const exception& e) { cerr << "文件错误:" << e.what(); } ``` 6. **异常安全注意事项** - 避免在析构函数中抛出异常 - 异常处理不应替代常规错误检查 - 注意资源泄漏问题(建议使用RAII技术) [^3]: GESP四级考纲明确要求掌握异常处理的基本应用,特别是在文件操作等场景中的实践能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值