码文异常不要怕,一篇文章精通应对【Java】中的异常(二)

简介: 码文异常不要怕,一篇文章精通应对【Java】中的异常(二)

1.7 编译时异常和运行时异常的区别🐢


Java中的异常被分为两大类:编译时异常和运行时异常,也称为受检异常和非受检异常

异常发生的原因有很多,通常包含以下几大类:


用户输入了非法数据。

要打开的文件不存在。

网络通信时连接中断,或者JVM内存溢出。

这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。-

要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:


编译时异常: 最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

必须显示处理,否则程序就会发生错误,无法通过编译

运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。

无需显示处理,也可以和编译异常一样处理

错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

运行时异常:


public static void main(String[] args) {
        method();
    }
    //运行时异常
    public static void method(){
        try {
            int arr[] = {1, 2, 3};
            System.out.println(arr[3]);//ArrayIndexOutOfBoundsException: 3
        }catch(ArrayIndexOutOfBoundsException e){
           e.printStackTrace();
        }
    }
}


public static void main(String[] args) {
        method1();
    }
    //编译时异常
    public static void method1(){
        try {
            String s = "2022-06-20";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date p = sdf.parse(s);
            System.out.println(p);
        }catch(ParseException e){
            e.printStackTrace();
        }
    }


1.8 异常处理之throws🐬


    格式: throws   异常类名:


注意:这个格式是跟在方法的括号后面的


如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。


也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。

下面方法的声明抛出一个 RemoteException 异常:


import java.io.*;
public class className
{
  public void deposit(double amount) throws RemoteException
  {
    // Method implementation
    throw new RemoteException();
  }
  //Remainder of class definition
}


一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。


例如,下面的方法声明抛出 RemoteException 和 InsufficientFundsException:


import java.io.*;
public class className
{
   public void withdraw(double amount) throws RemoteException,
                              InsufficientFundsException
   {
       // Method implementation
   }
   //Remainder of class definition
}


总结:


编译时异常必须进行处理,两种处理方案:try …catch …或者throws,如果采用throws这种方案,将来谁调用处理谁(还是try…catch…)

运行时异常可以不处理,出问题后,需要我们回来修改代码

1.9 声明自定义异常🦀

在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。


所有异常都必须是 Throwable 的子类。

如果希望写一个检查性异常类,则需要继承 Exception 类。

如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

格式:

public class 异常类名 extends Exception{

无参构造

带参构造

}


只继承Exception 类来创建的异常类是检查性异常类。


下面的 InsufficientFundsException 类是用户定义的异常类,它继承自 Exception。


一个异常类和其它任何类一样,包含有变量和方法。

范例:


public class ScoreException extends Exception {
    public ScoreException() {
    }
    public ScoreException(String message) {
        super(message);
    }
}


代码示例:


public class ScoreException extends Exception {
    public ScoreException() {
    }
    public ScoreException(String message) {
        super(message);
    }
}


public class Teacher {
    public  void checkScore(int score) throws ScoreException {
        if(score <0 ||score > 100){
            throw new ScoreException("分数异常,范围0-100");
        }else{
            System.out.println("分数正常");
        }
    }
}


import java.util.Scanner;
public class TeacherDemo {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.println("请输入学生成绩: ");
       int score = s.nextInt();
       Teacher t = new Teacher();
       try {
           t.checkScore(score);
       }catch(ScoreException e ){
           e.printStackTrace();
       }
    }
}


2.0 throw和throws的区别🐣


throws

throw

用在方法声明之后,跟的是异常类名

用在方法体内,跟的是异常对象名

表示抛出异常,由该方法的调用者来处理

表示抛出异常,由方法体内语句处理

表示出现异常的一种可能,并不一定会方法这种异常

执行throw一定抛出了某种异常


2.1 finally关键字🦋


finally 关键字用来创建在 try 代码块后面执行的代码块。


无论是否发生异常,finally 代码块中的代码总会被执行。


在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。


finally 代码块出现在 catch 代码块最后,语法如下:


try{
  // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}finally{
  // 程序代码
}


代码示例:


public class ExcepTest{
  public static void main(String args[]){
    int a[] = new int[2];
    try{
       System.out.println("Access element three :" + a[3]);
    }catch(ArrayIndexOutOfBoundsException e){
       System.out.println("Exception thrown  :" + e);
    }
    finally{
       a[0] = 6;
       System.out.println("First element value: " +a[0]);
       System.out.println("The finally statement is executed");
    }
  }
}


控制台输出:

Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3

First element value: 6

The finally statement is executed


注意下面事项:


catch 不能独立于 try 存在。

在 try/catch 后面添加 finally 块并非强制性要求的。

try 代码后不能既没 catch 块也没 finally 块。

try, catch, finally 块之间不能添加任何代码。

2.2 通用异常✨

在Java中定义了两种类型的异常和错误。


JVM(Java虚拟机) 异常: 由 JVM 抛出的异常或错误。例如:NullPointerException 类,ArrayIndexOutOfBoundsException 类,ClassCastException 类。

程序级异常: 由程序或者API程序抛出的异常。例如 IllegalArgumentException 类,IllegalStateException 类。

目录
相关文章
|
2月前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
80 1
|
2月前
|
Java API 调度
如何避免 Java 中的 TimeoutException 异常
在Java中,`TimeoutException`通常发生在执行操作超过预设时间时。要避免此异常,可以优化代码逻辑,减少不必要的等待;合理设置超时时间,确保其足够完成正常操作;使用异步处理或线程池管理任务,提高程序响应性。
91 12
|
2月前
|
Java
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
45 1
|
2月前
|
IDE 前端开发 Java
怎样避免 Java 中的 NoSuchFieldError 异常
在Java中避免NoSuchFieldError异常的关键在于确保类路径下没有不同版本的类文件冲突,避免反射时使用不存在的字段,以及确保所有依赖库版本兼容。编译和运行时使用的类版本应保持一致。
86 7
|
2月前
|
Java 编译器
如何避免在 Java 中出现 NoSuchElementException 异常
在Java中,`NoSuchElementException`通常发生在使用迭代器、枚举或流等遍历集合时,尝试访问不存在的元素。为了避免该异常,可以在访问前检查是否有下一个元素(如使用`hasNext()`方法),或者使用`Optional`类处理可能为空的情况。正确管理集合边界和条件判断是关键。
97 6
|
2月前
|
Java
Java异常捕捉处理和错误处理
Java异常捕捉处理和错误处理
70 1
|
2月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
86 2
|
JavaScript 前端开发 Java
|
11天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
13天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。