【JAVA SE】—— 异常(下)

简介: 【JAVA SE】—— 异常(下)

四、异常的体系结构

Java 内置了丰富的异常体系, 用来表示不同情况下的异常.
下图表示 Java 内置的异常类之间的继承关系

【JAVA SE】—— 异常 _异常体系、_07

顶层类 Throwable 派生出两个重要的子类, ErrorException

其中 Error 指的是 Java 运行时内部错误和资源耗尽错误. 应用程序不抛出此类异常. 这种内部错误一旦出现,
除了告知用户并使程序终止之外, 再无能为力. 这种情况很少出现.

Exception 是我们程序猿所使用的异常类的父类.

其中 Exception 有一个子类称为 RuntimeException , 这里面又派生出很多我们常见的异常类
NullPointerException , IndexOutOfBoundsException 等.

Java语言规范将派生于 Error 类或 RuntimeException 类的所有异常称为 非受查异常, 所有的其他异常称为 受查异常.

如果一段代码可能抛出受查异常,必须显式处理


受查异常与非受查异常

【JAVA SE】—— 异常 _自定义异常_08

Java语言规范将派生于 Error 类或 RuntimeException 类的所有异常称为非受查异常, 所有的其他异常称为受查异常。如果一段代码可能抛出 受查异常, 那么必须显式进行处理

public static void main(String[] args) { 
 System.out.println(readFile()); 
} 
public static String readFile() { 
 // 尝试打开文件, 并读其中的一行. 
 File file = new File("d:/test.txt"); 
 // 使用文件对象构造 Scanner 对象. 
 Scanner sc = new Scanner(file); 
 return sc.nextLine(); 
}
// 编译出错
Error:(13, 22) java: 未报告的异常错误java.io.FileNotFoundException; 必须对其进行捕获或声明以便抛出

如 FileNotFoundException 这样的异常就是受查异常,如果不显式处理, 编译无法通过,显式处理的方式有两种:


1.使用 try catch 包裹起来

因为在输入给sc时可能会出错,因此可以用try catch捕捉,此处虽然运行时可能会报错,但是会编译通过。这就是处理异常的好处。

public static void main(String[] args) { 
 System.out.println(readFile()); 
} 
public static String readFile() { 
 File file = new File("d:/test.txt"); 
 Scanner sc = null; 
 try { 
 sc = new Scanner(file); 
 } catch (FileNotFoundException e) { 
 e.printStackTrace(); 
 } 
 return sc.nextLine(); 
}

2.在方法上加上异常说明, 相当于将处理动作交给上级调用者

使用throws说明异常,则不需要在readFile方法内部使用try catch捕捉异常。如果main方法没有使用try catch捕捉异常则交给JVM处理,否则是自己捕捉异常。

public static void main(String[] args) { 
 try { 
 System.out.println(readFile()); 
 } catch (FileNotFoundException e) { 
 e.printStackTrace(); 
 } 
} 
public static String readFile() throws FileNotFoundException { 
 File file = new File("d:/test.txt"); 
 Scanner sc = new Scanner(file); 
 return sc.nextLine(); 
}

【JAVA SE】—— 异常 _java_09


五、自定义异常类

Java 中虽然已经内置了丰富的异常类, 但是我们实际场景中可能还有一些情况需要我们对异常类进行扩展, 创建符合我们实际情况的异常

注意:

  1. 自定义异常类继承Exception类默认是受查异常
  2. 继承RuntimeException类默认是非受查异常。

用户登录代码实例

public class Test {
    private static final String userName = "author";
    private static final String password = "12138";

    public static void login(String userName, String password) {
        if(!Test.userName.equals(userName)){// 用户名不相同,进入if语句
            System.out.println("用户名输入错误!");
        }
        if (!Test.password.equals(password)){
            System.out.println("password输入错误!");
        }
    }

    public static void main(String[] args) {
        login("author","12138");
    }
 }

我们的想法是将自定义一个用户登录错误异常

此处一个异常类继承Exception还是RuntimeException的意义:
我们来举个例子:
假设自定义异常类继承的都是RuntimeException,则此处编译时不会报错,因为继承RuntimeException是非受查异常,则在运行时才会报错。
代码1:

class NameException extends RuntimeException {
    public NameException(String name) {
        super(name);
    }
}
class PassWordException extends RuntimeException {
    public PassWordException(String message) {
        super(message);
    }
}
public class Test {
    private static String name = "hhh";
    private static String password = "1234";

    public static void login(String name, String password) throws NameException, PassWordException {
        if (!Test.name.equals(name)) {
            throw new NameException("名字错误");
        }
        if (!Test.password.equals(password)) {
            throw new PassWordException("密码错误");
        }
    }

    public static void main(String[] args) {
        login("hhh", "123");
    }
}

【JAVA SE】—— 异常 _异常捕捉_10

假设自定义异常类继承的都是Exception,则默认自定义异常类为受查异常,再用上面的代码,只将自定义继承改为Exception。则编译时期就会报错。

class NameException extends Exception {
    public NameException(String name) {
        super(name);
    }
}
class PassWordException extends Exception {
    public PassWordException(String message) {
        super(message);
    }
}
public class Test {
    private static String name = "bit";
    private static String password = "1234";

    public static void login(String name, String password) throws NameException, PassWordException {
        if (!Test.name.equals(name)) {
            throw new NameException("名字错误");
        }
        if (!Test.password.equals(password)) {
            throw new PassWordException("密码错误");
        }
    }

    public static void main(String[] args) {
        login("bit", "123");
    }
}

因为受查异常要用两种显示的方式进行处理,要不用try catch语句处理,要不抛出异常用throw和throws成对处理。

对于为何自定义一个异常类需要在构造方法中调用父类的构造方法。是因为我们可以在throw new NameException();时能够在括号中说明错的原因。而输入错的原因时又是一个字符串。我们在看Exception异常类的源码时,可以看到它也是继承了Throwable类。而其中也调用了构造方法。我们也已经知道了一个子类的构造方法是默认一个不带参数的调用父类的构造方法的。因此一切都能说通了。

【JAVA SE】—— 异常 _自定义异常_11


【JAVA SE】—— 异常 _异常_12


注意事项:

自定义异常通常会继承自 Exception 或者 RuntimeException
继承自 Exception 的异常默认是受查异常
继承自 RuntimeException 的异常默认是非受查异常.


目录
相关文章
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
392 1
|
3月前
|
安全 Java API
Java SE 与 Java EE 区别解析及应用场景对比
在Java编程世界中,Java SE(Java Standard Edition)和Java EE(Java Enterprise Edition)是两个重要的平台版本,它们各自有着独特的定位和应用场景。理解它们之间的差异,对于开发者选择合适的技术栈进行项目开发至关重要。
469 1
|
6月前
|
Java 程序员 数据库连接
我们详细地讲解一下 Java 异常及要如何处理
我是小假 期待与你的下一次相遇 ~
154 1
|
Java API 调度
如何避免 Java 中的 TimeoutException 异常
在Java中,`TimeoutException`通常发生在执行操作超过预设时间时。要避免此异常,可以优化代码逻辑,减少不必要的等待;合理设置超时时间,确保其足够完成正常操作;使用异步处理或线程池管理任务,提高程序响应性。
569 13
|
Java
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
234 1
|
6月前
|
设计模式 算法 Java
Java SE 与 Java EE 组件封装使用方法及实践指南
本指南详细介绍了Java SE与Java EE的核心技术使用方法及组件封装策略。涵盖集合框架、文件操作、Servlet、JPA、EJB和RESTful API的使用示例,提供通用工具类与基础组件封装建议,如集合工具类、文件工具类、基础Servlet、实体基类和服务基类等。同时,通过分层架构集成示例展示Servlet、EJB和JPA的协同工作,并总结组件封装的最佳实践,包括单一职责原则、接口抽象、依赖注入、事务管理和异常处理等。适合希望提升代码可维护性和扩展性的开发者参考。
213 0
|
9月前
|
SQL Java 中间件
【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常
在BeetISQL 2.13.8版本中,客户使用batch insert向yashandb表插入数据并尝试获取自动生成的sequence id时,出现类型转换异常。原因是beetlsql在prepareStatement时未指定返回列,导致yashan JDBC驱动返回rowid(字符串),与Java Bean中的数字类型tid不匹配。此问题影响业务流程,使无法正确获取sequence id。解决方法包括:1) 在batchInsert时不返回自动生成的sequence id;2) 升级至BeetISQL 3,其已修正该问题。
【YashanDB知识库】yasdb jdbc驱动集成BeetISQL中间件,业务(java)报autoAssignKey failure异常
|
9月前
|
SQL druid Oracle
【YashanDB知识库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIER start异常
客户Java日志中出现异常,影响Druid的merge SQL功能(将SQL字面量替换为绑定变量以统计性能),但不影响正常业务流程。原因是Druid在merge SQL时传入null作为dbType,导致无法解析递归查询中的`start`关键字。
|
10月前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
639 14
|
10月前
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
2025 5