Java异常处理机制(完结篇)——再看不懂我找不到女朋友

简介: Java异常处理机制(完结篇)——再看不懂我找不到女朋友

异常处理

异常:

对于计算机程序来说,我们不会保证我们写的程序不会出任何问题,就算程序设计没有逻辑错误,那么你能够保证用户会合法按照自己的意愿去输入数据吗?就算用户相当的配合你,你能够保证你在运行程序时不会出现其他问题吗?比如说网络突然中断,或者是电源中断等。

那么我们就要在设计程序时就要考虑到这些问题,保证当程序运行出错时,有相对应的解决方案,而不是直接将异常直接抛到虚拟机导致程序终止运行。

常出现的异常

  • IndexOutOfException:一般是数组下标越界异常
int[] arr=new int[10];
System.out.println(arr[20]);

  • NullPointException:空指针
String string=null;
string.charAt(0);

  • NumberFormatException:数值类型转换错误
String string="abc";
Integer a=Integer.parseInt(string);

  • ArithmeticException:算术异常
int a=2;
int b=0;
a=a/b;

  • ClassCastException:引用类型转换异常
public class Main {
    public static void main(String[] args) {
        String string="";
        Animal dog=new Dog();
        Cat cat=(Cat)dog;
    }
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}

异常处理机制

方式一:try…catch

try {
      //执行代码
}catch (Exception e){
      //解决方案
}

例如当我们计算1/0时,这是会有算术错误,我们可以捕捉在运算时产生的算术异常

try {
      int a=2/0;
}catch (ArithmeticException e){
      e.printStackTrace();
}

这样在遇到算术异常时,我们的catch语句就会捕捉这个异常,进行解决

  • 可以采用多个catch块去捕捉多个异常
  • 但是要注意,小异常放在上面,大异常放在下面
  • 因为大异常是他们的父类,一但它放在上面,其余的小异常就不会被执行
  • 所以优先处理小异常,这样才会使结构清晰,处理更加明确

当我们在try语句块中执行某条语句产生异常时,在它之后的代码就不会执行,此时会转到执行捕捉到该异常的catch块中执行相应语句

在try语句块中定义的变量为局部变量,在catch语句块中是无法访问的

方式二:多异常捕获

从Java7开始,一个catch块可以捕获多种多样的异常

  • 捕获多种异常时,多种异常类型之间用竖线|隔开
  • 捕获多种异常时,异常变量由隐式的final修饰,不能够对该异常变量重新赋值
try {
  int a=1/0;
}catch (ArithmeticException |IndexOutOfBoundsException e){
    System.out.println("程序产生了算术异常或数组越界异常");
    //e=new Exception();改段代码会报错,因为catch括号里面的变量e被final修饰,不可重新赋值
}catch (Exception e){
    e=new Exception();
}

由于多异常捕捉模式的变量是被final修饰的,所以在catch语句块中是无法给变量重新赋值的

方式三:try…catch…finally

当我们在某些时候,在try语句块中会打开一些文件,或者连接数据库等操作,那么一但我们在try语句块中产生了异常,那么我们之后的代码就不会执行,导致文件和数据库等不能及时正确关闭。

  • Java的垃圾回收机制是不会回收任何物理资源,只会回收堆内存中对象所占用的内存

为了保证可以及时回收try里面打开的物理资源,Java异常处理机制提供了finally语句块,这个语句块是在执行完try和catch语句块后,必须要执行的一个代码块,如果在try或者catch中return语句,也不会影响finally的执行,执行完finally后,再去执行return,如果finally中有return语句,那么try和catch语句块中的return就不会被执行,但是有一点如果在try中的是System.exit(1),就不会去执行finally语句块了,因为这样会导致直接退出虚拟机。

FileWriter file=null;
try{
      file=new FileWriter("text.txt");
}catch (IOException e){
      e.printStackTrace();
}finally {
      if(file!=null){
           try {
                file.close();
           } catch (IOException e) {
                e.printStackTrace();
    }
  }
}

这样一但try块出现异常,该代码依然会执行finally中的close方法将文件关闭

Java7、9增强的自动关闭资源的try语句

当我们在finally中执行关闭资源的代码时,程序显得很臃肿

Java7:
  • Java7增强了try语句的功能,它允许我们在try后面紧跟一对括号,括号里面可以声明定义一些资源
  • 当我们执行完try语句后,程序会自动帮我们关闭资源
  • 这些资源必须实现AutoCloseable接口或者是Closeable接口的close方法
  • Close接口是AutoCloseable的子接口
try (FileWriter file=new FileWriter("text.txt")) {
     file.write("");    
}catch(Exception e){
     e.printStackTrace();
}
Java9:
  • Java9进一步增强该操作,不需要再括号内声明定义了
  • 可以在try语句外面定义
  • 但是该资源变量必须是final或者是有效final就是始终没有被赋过其他值
FileWriter file1=new FileWriter("text.txt");
FileWriter file2=new FileWriter("text.txt");
try(file1;file2){
      file.write("");
}catch(Exception e){
      e.printStackTrace();
}

Checked异常和Runtime异常

对于Java中的异常可分为两大类:

一类是Check异常(编译时异常):

一类是Runtime异常(运行时异常):

所有的RuntimeException类及其子类的异常都是运行时异常,其余是编译时异常

运行时异常是指我们程序在运行后才会出现的异常,这类异常不影响编译,只是在运行过程会发生错误

但是编译时异常,我们必须去显示的处理该异常,否则我们不能通过编译,例如当我们在调用多线程中的sleep方法时,

我们需要用try…catch包住才可以使用,否则就会报错,因为该方法在定义时,抛出了编译异常,需要我们显式处理

使用throws抛出异常

  • 当我们有时不知道如何去处理该异常时,我们就需要将产生的异常对象向上抛
  • 方法会抛给main方法,如果在main方法中没有得到解决,就会继续向上抛
  • 抛给Java虚拟机,打印异常跟踪栈信息,并终止程序运行
  • 这也就是为什么之前我们运行的程序在运行失败后程序会终止,而且在控制台打印一些红色的错误
public static void main(String[] args) throws IOException {
        test();
}
public static void test() throws IOException {
        int a=2/0;
}
public static void main(String[] args){
        try {
            test();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
public static void test() throws IOException {
        int a=2/0;
    }
}

注意:

  • 但我们调用抛出异常的方法时,这个方法要么在try…catch语句块中
  • 要么在另一个带throws的方法中
  • 因为既然方法抛出了异常就要去捕捉进行解决

方法重写时抛异常注意事项

当我们的子类继承父类时,如果父类的方法抛出了异常

子类重写该方法的时候抛出的异常不得大过父类抛出的异常

class A{
    public void test() throws ArithmeticException{
    }
}
class B extends A{
    @Override
    public void test() throws Exception {
    }
}

上述代码会报错,因为子类B抛出的是Exception异常大过父类抛出的异常

使用throw抛出异常

在某些情景下,不一定是真正的异常,只要是不符合我们预期的想法就是异常

当不符合预期时,我们可以手动去抛出异常

public static void main(String[] args){
        int a=-1;
        try {
            if(a<0){
                throw new Exception("a为负数");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

对于Check异常我们要么显式捕捉处理,要么继续抛

而Runnable异常,我们既可以显式捕捉,也可以不予理会

自定义异常类

因为Java定义的异常有限,有时并不会满足我们的需求,这时我们就需要自己去定义一个异常类,实现我们所需要的功能

  • 首先要继承Exception类或者是RuntimeException等基类
  • 然后定义两个构造器
  • 有参构造器通常传入的是错误信息
class MyException extends Exception{
    public MyException(){
    }
    public MyException(String msg){
        super(msg);
    }
}

总结

  • 异常只是应用于处理非正常的情况,不要过度使用异常来代替正常的流程控制
  • 对于一些可预知的错误,程序员完全有能力提供相应代码去处理,而不是去抛异常

例如:

int a[]=new int[10];
for(int i=0;i<100;i++){ 
   try {
       System.out.println(a[i]);
   }catch (IndexOutOfBoundsException e){
       e.printStackTrace();
   }
}
  • 这种情况程序员是可以预料到的,完全有能力利用代码去避免这种错误的发生
    而不是一味的去抛异常再去解决
  • 这种抛异常虽然简单,但是Java运行时捕捉到异常后,还要进入catch块
    这样会降低运行效率
  • 异常处理机制的初衷是将不可预期异常的处理代码和正常的业务逻辑处理代码分离,
    绝不要使用异常处理来代替正常的业务逻辑判断


目录
相关文章
|
1月前
|
Java 程序员
Java中的异常处理机制
【2月更文挑战第22天】在Java编程中,异常处理是一个重要的概念。它允许程序员在程序执行过程中遇到错误时,对错误进行处理,而不是让程序崩溃。本文将介绍Java中的异常处理机制,包括异常的分类、如何捕获和处理异常以及自定义异常等内容。
|
3月前
|
Java
请解释Java中的异常处理机制,并给出使用try-catch块的示例。
请解释Java中的异常处理机制,并给出使用try-catch块的示例。
|
7月前
|
Java 数据库连接
深入理解Java中的异常处理机制
在Java开发中,异常处理是一项重要的技术。它允许我们识别和处理程序运行时可能出现的错误条件,从而提高程序的稳定性和可靠性。本篇博客将深入探讨Java中的异常处理机制,并介绍如何正确地使用异常处理来编写健壮的代码。
127 0
|
5天前
|
Java 数据库连接
深入理解Java异常处理机制
【4月更文挑战第24天】本文将探讨Java中的异常处理机制,包括异常的概念、分类、捕获和抛出等方面。通过深入了解异常处理机制,可以帮助我们编写更加健壮的程序,提高代码的可读性和可维护性。
|
29天前
|
Java 程序员 开发者
深入理解Java异常处理机制
在Java编程中,异常处理是确保程序健壮性与稳定性的重要组成部分。本文旨在深度剖析Java异常处理机制的核心概念、结构及其实际应用策略,帮助开发者更好地理解并运用异常处理来优化程序设计。我们将从Java异常体系结构入手,探讨try-catch-finally语句块的执行流程,分析自定义异常的必要性与实现方式,并通过实例演示如何有效地管理和处理异常情况。
23 3
|
2月前
|
Java 数据库连接
Java中的异常处理机制及其应用
【2月更文挑战第5天】异常处理是Java程序设计中非常重要的一部分。本文将介绍Java中的异常处理机制,包括异常的分类、捕获和处理方式。同时,还将探讨异常处理在实际开发中的应用,并给出一些实例代码。
|
2月前
|
Java 编译器 开发者
Java中的异常处理机制详解
Java中的异常处理机制详解
|
4月前
|
安全 Java 程序员
【Java 异常处理】异常处理机制,内置异常类,如何捕获异常
【Java 异常处理】异常处理机制,内置异常类,如何捕获异常
|
5月前
|
安全 Java 程序员
JAVA异常处理(三种异常处理机制)
异常是程序在编译或执行的过程中可能出现的问题,语法错误不算在异常体系提前处理异常,程序会更加安全Error: 系统级别问题、JVM退出等,代码无法控制Exception: Java.lang包下,称为异常类,它表示程序本身可以处理的问题 Runtime Exception及其子类: 运行时异常,编译阶段不会报错(如空指针,数组索引越界异常) 除Runtime Exception之外所有异常:
73 0
|
6月前
|
Java
超详细的Java异常处理机制知识整理2
超详细的Java异常处理机制知识整理2