【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 的异常默认是非受查异常.


目录
相关文章
|
7天前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
|
7天前
|
Java
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
|
8天前
|
IDE 前端开发 Java
怎样避免 Java 中的 NoSuchFieldError 异常
在Java中避免NoSuchFieldError异常的关键在于确保类路径下没有不同版本的类文件冲突,避免反射时使用不存在的字段,以及确保所有依赖库版本兼容。编译和运行时使用的类版本应保持一致。
|
10天前
|
Java 编译器
如何避免在 Java 中出现 NoSuchElementException 异常
在Java中,`NoSuchElementException`通常发生在使用迭代器、枚举或流等遍历集合时,尝试访问不存在的元素。为了避免该异常,可以在访问前检查是否有下一个元素(如使用`hasNext()`方法),或者使用`Optional`类处理可能为空的情况。正确管理集合边界和条件判断是关键。
|
12天前
|
Java
Java异常捕捉处理和错误处理
Java异常捕捉处理和错误处理
14 1
|
14天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
32 2
|
21天前
|
Java
如何在 Java 中处理“Broken Pipe”异常
在Java中处理“Broken Pipe”异常,通常发生在网络通信中,如Socket编程时。该异常表示写入操作的另一端已关闭连接。解决方法包括:检查网络连接、设置超时、使用try-catch捕获异常并进行重试或关闭资源。
|
24天前
|
存储 安全 Java
如何避免 Java 中的“ArrayStoreException”异常
在Java中,ArrayStoreException异常通常发生在尝试将不兼容的对象存储到泛型数组中时。为了避免这种异常,确保在操作数组时遵循以下几点:1. 使用泛型确保类型安全;2. 避免生类型(raw types)的使用;3. 在添加元素前进行类型检查。通过这些方法,可以有效防止 ArrayStoreException 的发生。
|
25天前
|
人工智能 Oracle Java
解决 Java 打印日志吞异常堆栈的问题
前几天有同学找我查一个空指针问题,Java 打印日志时,异常堆栈信息被吞了,导致定位不到出问题的地方。
31 2
|
28天前
|
Java 索引
如何避免在 Java 中引发`StringIndexOutOfBoundsException`异常
在Java中,处理字符串时若访问了不存在的索引,会抛出`StringIndexOutOfBoundsException`异常。为避免此异常,应确保索引值在有效范围内,例如使用`length()`方法检查字符串长度,并确保索引值不小于0且不大于字符串长度减1。