谈谈我对Exception和Error的理解(未完)

简介:

image

NoClassDefFoundError/ClassNotFoundException

NoClassDefFoundError发生在jvm运行时,执行某个方法或者静态成员时,如果jvm加载不到该类时报错的错误。本地编译没报错,但运行时报错,有可能该类对类加载器而言是不可见的。

ClassNotFoundException发生与编译时根据classpath找不到对应类时报的错误。

由于User类为"private"修饰,Test.java里的main无权访问,编译时不会报错到运行时因找到User类NotClassDefFoundError:

import java.util.ArrayList;
import java.util.List;

/**
 * Created by fujianbo on 2018/5/12.
 *
 * @author fujianbo
 * @date 2018/05/12
 */
public class Test {
    public static void main(String args[]){
        List<User> users = new ArrayList<>(2);
        try {
            users.add(new User("1234"));
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

class User{
    private static String USER_ID = getUserId();

    public User(String id){
        this.USER_ID = id;
    }
    private static String getUserId() {
        throw new RuntimeException("UserId Not found");
    }
}

不良案例

捕获时异常要明确异常类型,提高代码可读性

public class Test {
    public static void main(String args[]){
        try {
            Thread thread = new Thread();
            // do something
            // ...
            thread.wait();
        } catch (InterruptedException e) {
            
        }
    }
}

捕获异常范围不宜过大

RuntimeException更应该扩散而不是捕获(很多时候我们并不能处理这类异常),如Throwable或则Error也是如此。

不要使用标准输出打印异常

try {
        Thread thread = new Thread();
        // do something
        // ...
        thread.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
}

使用e.printStackTrace将导致异常堆栈输出到标准异常流,这很难判断日志最终被输出都哪里而丧失监控的意义。

throw early & catch late原则

public static void main(String args[]){
        loadFile(null);
    }

    private static void loadFile(String fileName) {
        try {
            FileInputStream fileInputStream = new FileInputStream(fileName);
            func1(fileInputStream);
            func2(fileInputStream);
        } catch (FileNotFoundException e) {
            // take logs here
        }

    }
    
    private static void func1(FileInputStream fileInputStream) {
        if (fileInputStream == null) {
            return;
        }
        // do something
    }
    
    private static void func2(FileInputStream fileInputStream) {
        // do something
    }

throw early可节省查看堆栈排查问题的时间,无论使用断言还是if判断都可以简单做到。

自定义异常

  • Checked Exception的初衷为从异常中恢复,哪些要恢复以及怎么恢复依赖于精细化的异常分类
  • 异常信息不要包含敏感信息,这是ConnectionException不打印ip和端口信息的原因

Checked Exception Or Unchecked Exception?

  • [引用自某博客,出处后续补上]虽然反对使用Checked Exception的声音不少,但Checked Exception在提示不要忘记处理异常,虽然调用该方法的方法体需要申明外抛异常,但至少可以指导底层会抛哪些异常,在自定义异常时提供了有效信息(异常种类划分&处理)
  • Unchecked Exception使代码更简洁,但容易丢失详细堆栈信息。如调用链路横跨多个流程,每个流程涉及到的方法调用都有上下文,哪一步出错可以依赖不同流程的上下文打印信息,快速定位问题。
  • try/catch代码块产生额外的性能开销,影响jvm优化(尽量缩小try/catch块的大小)
  • 实例化一个Exception会保留执行时的堆栈快照,该过程为相对较重的操作。

思考

Reactive Stream(异步、基于事件机制),出现异常不能简单外抛。由于代码堆栈不在是同步调用时的垂直结构,我们看到的是特定executor的堆栈。那如何处理这类异常呢?(未完待续...)

目录
相关文章
|
前端开发 NoSQL Java
谷粒学苑笔记整理
谷粒学苑笔记整理
478 0
|
存储 算法 生物认证
活体检测的几种手段分析
活体检测的手段比较多,目前比较通用的是人脸活体检测,但是实际应用中的还有指纹识别、虹膜识别、静脉识别,通过这些手段来增加安全性,活体检测在金融领域、军事管理中最先使用,目前也在渐渐的普及到各个民用行业。
867 0
活体检测的几种手段分析
|
存储 监控 C语言
西门子S7-1200编程实例,关断延迟定时器指令如何使用?
在西门子S7-1200中有四种类型的定时器:TON接通延迟定时器、TONR保持型接通延迟定时器、TOF关断延迟定时器、TP脉冲定时器。
西门子S7-1200编程实例,关断延迟定时器指令如何使用?
|
人工智能 IDE 开发工具
《C++人工智能开发 IDE 全解析:助力智能创新之路》
本文深入探讨了几款适合 C++ 人工智能开发的 IDE,包括 Visual Studio、CLion、Eclipse CDT 和 Qt Creator。每款 IDE 都有其独特的优势,如 Visual Studio 的强大调试工具、CLion 的代码导航和 CMake 支持、Eclipse CDT 的跨平台能力和丰富的插件生态系统,以及 Qt Creator 在界面开发方面的卓越表现。开发者应根据项目需求、团队协作和个人习惯选择最合适的 IDE,以提升开发效率和体验。
374 16
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
NeurIPS 2024:真实世界复杂任务,全新基准GTA助力大模型工具调用能力评测
在NeurIPS 2024会议上,GTA(General Tool Agents Benchmark)基准测试被提出,旨在评估大型语言模型(LLM)在真实世界复杂任务中的工具调用能力。GTA采用真实用户查询、真实部署工具和多模态输入,全面评估LLM的推理和执行能力。结果显示,现有LLM在真实世界任务中仍面临巨大挑战,为未来研究提供了重要方向。
355 13
|
机器学习/深度学习 自然语言处理 算法
政府部门文档管理革新:实现90%自动内容抽取与智能标签化处理!
本文介绍了多模态数据处理技术,涵盖自然语言处理(NLP)、光学字符识别(OCR)和图像识别的技术原理,以及智能分类、标签化处理、系统集成与国产化适配、安全与合规、算法优化等方面的内容。通过这些技术的应用,实现了文档管理的全流程智能化,为用户提供高效、可靠的解决方案。
388 3
|
JavaScript 应用服务中间件 API
Node.js搭建REST API实战:从基础到部署
【7月更文挑战第18天】通过以上步骤,你可以将你的Node.js REST API从开发环境顺利迁移到生产环境,并利用各种工具和技术来确保应用的稳定性、安全性和可扩展性。
|
存储 关系型数据库 MySQL
什么是覆盖索引?
本章主要讲解了索引覆盖和回表的相关知识
377 0
|
运维 监控 NoSQL
两张流程图带你学会SpringBoot整合Redis主从复制、哨兵模式并搞懂其工作流程
两张流程图带你学会SpringBoot整合Redis主从复制、哨兵模式并搞懂其工作流程
840 0