Java 异常的捕获及处理

简介: 在Java中程序的错误主要是语法错误和语义错误。一个程序即使在编译时没有错误信产生,在运行时也有可能出现各种各样的错误导致程序退比,那么这些错误在Java中统一称为异常,在Java中对异常的处理提供了非常方便的操作。

1、异常的基本概念


异常:就是在程序运行过程产生的错误,它会中断正在运行的程序。


Java异常是Java提供的用于处理程序中错误的一种机制。所谓错误是指在程序运行的过程中发生的一些异常事件(如:除0溢出,数组下标越界,所要读取的文件不存在)。


设计良好的程序应该在异常发生时提供处理这些错误的方法,使得程序不会因为异常的发生而阻断或产生不可预见的结果。


Java程序的执行过程中如出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息并将被提交给Java运行时系统,这个过程称为抛出(throw)异常。


当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这一过程称为捕获(catch)异常。


public class Test {
  public static void main(String[] args) {
       String friends [] ={ "Tom","John","Jenni" };
       for (int i = 0;i < 4;i++){
           System.out.println(friends[i]);.
       }
   }
}


🌻在Java之中如果要进行异常的处理,可以使用:try、catch、finally这几个关键字来完成,其基本的处理结构如下:


try{
       //可能出现异常的语句
}[catch(异常类型 异常对象){
       //异常处理
}catch(异常类型 异常对象){
       //异常处理
}catch(异常类型 异常对象){
       //异常处理
}.....] [finally {
       不管异常是否处理都要执行 ;
}]


🌻处理异常


public class Demo{
    public static void main(String args[]) {
        System.out.println("【1】*****程序开始执行*****") ; 
        try {
               System.out.println("【2】数学计算:" +(10 / 0)) ;   
        } catch (ArithmeticException e) {
               System.out.println("【c】处理异常:" + e) ;          //处理异常
        }
        System.out.println("【3】*****程序执行完毕*****") ;    
     }     
}


此时可以发现现在即便出现了异常,程序也可以正常执行完毕,所以此时的设计属于一个合理设计。但是有一个问题出现了,此时在进行异常处理的时候直接输出的是一个异常类的对象,那么对于此对象如果直接打印(调用toString())所得到的异常信息并不完整,如果要想获得非常完整的异常信息,则可以使用异常类中提供的printStackTrace()方法完成。


对于异常的处理格式也可以在最后追加有一个finally的程序块,表示异常处理后的出口,不管是否出现异常都执行。


🌻范例:使用finally语句


public class Demo{
    public static void main(String args[]) {
        System.out.println("【1】*****程序开始执行*****") ; 
        try {
              System.out.println("【2】数学计算:" +(10 / 0)) ;   
        } catch (ArithmeticException e) {
              e.printStackTrace() ;
        }finally {
                  System.out.println("【F】不管是否出现异常,我都会执行。") ;
        }
        System.out.println("【3】*****程序执行完毕*****") ;    
    }     
}
此时程序中有异常执行finally,没有异常也执行finally。


🌻在整个Java的异常处理中,实际上也是按照面向对象的方式进行处理,处理的步骤如下:

(1)一旦产生异常,则首先会产生一个异常类的实例化对象。

(2)在try语句中对此异常对象进行捕捉。

(3)产生的异常对象与catch语句中的各个异常类型进行匹配,如果匹配成功,则执行catch语句中的代码。


2、throws与throw关键字


(1)throws关键字

在定义一个方法时可以使用throws关键字声明,使用throws声明的方法表示此方法不处理异常,而交给方法的调用处进行处理。


🌻throws使用格式如下:

public 返回值类型 方法名称(参数列表···)throws 异常类{ }


🌻范例:使用throws关键字处理异常


class Math {
  public int div (int i,int j ) throws Exception { //方法可以不处理异常
     int temp=i/j;
     return temp;
  }
}
public class ThrowsDemo{
  public static void main(String[] args){
    Math m=new Math();
    try{     //因为有throws,不管是否有异常,都必须处理
      System.out.println("除法操作:"+m.div(10,2));
    }catch(Exception e){
      e.printStackTrace();
    } 
  }
}



🌻运行结果:


除法操作:5


主方法也可以使用throws关键字,但是主方法是程序的起点,所以此时主方法再向上抛异常,则只能将异常抛给JVM进行处理。


class Math {
  public int div (int i,int j ) throws Exception { //方法可以不处理异常
     int temp=i/j;
     return temp;
  }
}
public class ThrowsDemo2{
   //本方法中的所有异常都可以不使用try catch处理的
  public static void main(String[] args) throws Exception {
    Math m=new Math();
    System.out.println("除法操作:"+m.div(10,2));
  }
}


🌻运行结果:


除法操作:5


(2)throw关键字

与throws不同的是,可以直接使用throw抛出一个异常,抛出时直接抛出异常类的实例化对象即可。


🌻范例:


public class ThrowDemo{ 
  public static void main (String[] args){
    try{
      throw new Exception("自己抛出的异常!")
    }catch(Exception e) {
        System.out.println(e);
    }
}


异常产生时肯定会由系统产生一个异常类的实例化对象,只是此时异常类的实例化对象是手工产生的。


(3)范例throw与throws的应用

try···catch···finally、throw、throws联合使用


🌻范例:


class Math{
  public int div(int i,int j) throws Exception{
    System.out.println("计算开始。");
    int temp=0;
    try{
      temp=i/j;
    }catch(Exception e){
      throws e;
    }finally{
      System.out.println("计算结束。");
    }
    return temp;
  }
}
public class ThrowDemo2{
  public static void main(String[] args){
    Math m=new Math();
    try{
      System.out.println("除法操作:"+m.div(10,2));
   }catch(Exception e){
     System.out.println("异常产生:"+e);
   }
 }
}


🌻运行结果:


计算开始。
计算结束。
异常产生:Dava.lang.ArithmeticException: / by zero


具体执行流程图:

image.png


3、Exception类与RuntimeException类


对于这个将字符串变为int类型的代码:int temp=Integer.parseInt(str);


Integer因为开头首字母大写,所以肯定是一个类,而parseInt()方法可以直接由类名称调用,所以此方法肯定是一个静态方法,此方法定义如下:


public static int parseInt (String s) throws NumberFormatException;

观察NumberFormatException类的继承关系:

image.png


🌻NumberFormatException属于RuntimeException的子类,那么这时就可以清楚地知道以下概念:


Exception在程序中必须使用try···catch进行处理。

RuntimeException可以不使用try···catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。


4、自定义异常类


在Java中已经提供了大量的异常类,但是这些异常类有时也很难满足开发者的要求,所以用户可以根据自己的需要定义自己的异常类。定义异常类只需要继承Exception类即可。


🌻范例:


class MyException extends Exception{// 自定义异常类
  public MyException(String msg){
    super(msg);
  }
}
public class Demo{
  public static void main(String[] args){
    try{
      throws new MyException("自定义异常。");//抛出异常
    }catch(Exception e){//异常处理
      System.out.println(e);
    }
  }
}


🌻运行结果:


MyException:自定义异常。


5、断言


在JDK 1.4之后,Java中增加了断言的功能。断言就是肯定某一个结果的返回值是正确的,如果最终此结果的返回值是错误的,则通过断言检查肯定会提示错误信息。


🌻断言的定义格式如下:


assert boolean 表达式;
assert boolean 表达式:详细的信息


如果以上boolean表达式的结果为frue,则什么错误信息都不会提示;如果为false,则会提示错误信息;如果没有声明详细信的描述,则系统会使用默认的错误信息提示方式。


🌻范例:


public class Demo{
  public static void main(String[] args){
    int x[]={1,2,3};
    assert x.length==0;//此处使用断言,结果为false
  }
}


此处的断言结果是错误的,但此时运行程序并不会得到任何的结果,这是因为Java在设计此关键字时,考虑到了系统的应用,为了防止某些用户使用assert作为关键字,所以在程序正常运行时断言并不会起任何的作用.


如果要想让断言起作用,则在使用Java运行时应该加入参数:—enableassertions 也可以简写为-ea


🌻运行程序格式如下:


编译程序:javac Demo.java
验证程序:java -ea Test

🌻程序运行时出现以下错误:


Exception in thread “main” Java. lang.AssertionError at Test.main(Demo.java:4)


注意断言的使用:

(1)虽然断言返回的是boolean值,但是并不能将其作为条件判断语句。

(2)断言虽然有检查运行结果的功能,但是一般在开发中并不提倡使用断言。


目录
相关文章
|
8天前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
|
8天前
|
Java
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
|
1月前
|
算法 Java 开发者
Java中的异常处理:理解、捕获与预防
【9月更文挑战第37天】在Java编程的旅途中,异常处理是一道必经的桥梁。它不仅关乎代码的健壮性,还体现了开发者对不可预见事件的预判与应对。本文将带你深入理解Java异常的本质,学习如何巧妙地捕获和处理它们,并探讨预防异常的最佳实践,让你的代码在风浪中稳健前行。
|
9天前
|
IDE 前端开发 Java
怎样避免 Java 中的 NoSuchFieldError 异常
在Java中避免NoSuchFieldError异常的关键在于确保类路径下没有不同版本的类文件冲突,避免反射时使用不存在的字段,以及确保所有依赖库版本兼容。编译和运行时使用的类版本应保持一致。
|
11天前
|
Java 编译器
如何避免在 Java 中出现 NoSuchElementException 异常
在Java中,`NoSuchElementException`通常发生在使用迭代器、枚举或流等遍历集合时,尝试访问不存在的元素。为了避免该异常,可以在访问前检查是否有下一个元素(如使用`hasNext()`方法),或者使用`Optional`类处理可能为空的情况。正确管理集合边界和条件判断是关键。
|
13天前
|
Java
Java异常捕捉处理和错误处理
Java异常捕捉处理和错误处理
14 1
|
15天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
34 2
|
22天前
|
Java
如何在 Java 中处理“Broken Pipe”异常
在Java中处理“Broken Pipe”异常,通常发生在网络通信中,如Socket编程时。该异常表示写入操作的另一端已关闭连接。解决方法包括:检查网络连接、设置超时、使用try-catch捕获异常并进行重试或关闭资源。
|
25天前
|
存储 安全 Java
如何避免 Java 中的“ArrayStoreException”异常
在Java中,ArrayStoreException异常通常发生在尝试将不兼容的对象存储到泛型数组中时。为了避免这种异常,确保在操作数组时遵循以下几点:1. 使用泛型确保类型安全;2. 避免生类型(raw types)的使用;3. 在添加元素前进行类型检查。通过这些方法,可以有效防止 ArrayStoreException 的发生。
|
26天前
|
人工智能 Oracle Java
解决 Java 打印日志吞异常堆栈的问题
前几天有同学找我查一个空指针问题,Java 打印日志时,异常堆栈信息被吞了,导致定位不到出问题的地方。
33 2
下一篇
无影云桌面