亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> java

Java - 异常

异常(或异常事件)是在程序执行期间出现的问题。当异常 发生程序的正常流程被打断,程序/应用程序异常终止,不推荐,所以要处理这些异常。

由于许多不同的原因,可能会发生异常。以下是一些发生异常的场景。

其中一些异常是由用户错误引起的,另一些是由程序员错误引起的,还有一些是由以某种方式发生故障的物理资源引起的。

基于这些,我们将异常分为三类。您需要了解它们才能知道 Java 中的异常处理是如何工作的。

例如,如果您使用 FileReader 程序中的类从文件中读取数据,如果在其构造函数中指定的文件不存在,则 FileNotFoundException 发生,编译器提示程序员处理异常。

示例

现场演示
import java.io.File;
import java.io.FileReader;

public class FilenotFound_Demo {

   public static void main(String args[]) {		
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file); 
   }
}

如果你尝试编译上面的程序,你会得到以下异常。

输出

C:\>javac FilenotFound_Demo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
      FileReader fr = new FileReader(file);
                      ^
1 error

注意 - 由于方法 read()close() FileReader 类抛出 IOException,您可以观察到编译器通知处理 IOException,以及 FileNotFoundException。

例如,如果您在程序中声明了一个大小为 5 的数组,并尝试调用第 6 th 数组的元素,然后是 ArrayIndexOutOfBoundsExceptionexception 发生。

示例

现场演示
public class Unchecked_Demo {
   
   public static void main(String args[]) {
      int num[] = {1, 2, 3, 4};
      System.out.println(num[5]);
   }
}

如果编译执行上面的程序,会得到如下异常。

输出

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)

异常层次结构

所有异常类都是 java.lang.Exception 类的子类型。异常类是 Throwable 类的子类。除了异常类之外,还有另一个名为 Error 的子类,它是从 Throwable 类派生的。

错误是在严重故障的情况下发生的异常情况,Java 程序不处理这些情况。生成错误以指示运行时环境生成的错误。示例:JVM 内存不足。通常,程序无法从错误中恢复。

Exception 类有两个主要子类:IOException 类和 RuntimeException 类。

以下是最常见的选中和未选中 Java 内置异常的列表。

异常方法

以下是 Throwable 类中可用的重要方法列表。

Sr.No. 方法和说明
1

公共字符串 getMessage()

返回有关已发生异常的详细消息。此消息在 Throwable 构造函数中初始化。

2

public Throwable getCause()

返回由 Throwable 对象表示的异常原因。

3

公共字符串 toString()

返回与 getMessage() 的结果连接的类的名称。

4

public void printStackTrace()

将 toString() 的结果连同堆栈跟踪打印到错误输出流 System.err。

5

公共 StackTraceElement [] getStackTrace()

返回包含堆栈跟踪上的每个元素的数组。索引为 0 的元素代表调用堆栈的顶部,数组中的最后一个元素代表调用堆栈底部的方法。

6

public Throwable fillInStackTrace()

用当前堆栈跟踪填充此 Throwable 对象的堆栈跟踪,添加到堆栈跟踪中的任何先前信息。

捕捉异常

一个方法使用 try 的组合来捕获异常 和捕捉 关键词。在可能产生异常的代码周围放置了一个 try/catch 块。 try/catch 块中的代码称为受保护代码,使用 try/catch 的语法如下所示 -

语法

try {
   // Protected code
} catch (ExceptionName e1) {
   // Catch block
}

容易出现异常的代码放在try块中。当发生异常时,发生的异常由与其关联的 catch 块处理。每个 try 块应该紧跟一个 catch 块或 finally 块。

catch 语句涉及声明您尝试捕获的异常类型。如果受保护代码中发生异常,则检查 try 之后的 catch 块(或多个块)。如果发生的异常类型列在 catch 块中,则将异常传递给 catch 块,就像将参数传递给方法参数一样。

示例

下面是一个声明了 2 个元素的数组。然后代码尝试访问 3 rd 引发异常的数组元素。

现场演示
// File Name : ExcepTest.java
import java.io.*;

public class ExcepTest {

   public static void main(String args[]) {
      try {
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

这将产生以下结果 -

输出

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

多个 Catch 块

一个 try 块后面可以跟多个 catch 块。多个 catch 块的语法如下所示 -

语法

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}

前面的语句演示了三个 catch 块,但您可以在一次尝试后获得任意数量的 catch 块。如果受保护代码中发生异常,则将异常抛出到列表中的第一个 catch 块。如果抛出的异常的数据类型与 ExceptionType1 匹配,则会在此处捕获。如果不是,则异常传递到第二个 catch 语句。这种情况一直持续到异常被捕获或通过所有捕获,在这种情况下,当前方法停止执行,异常被抛出到调用堆栈上的前一个方法。

示例

下面是展示如何使用多个 try/catch 语句的代码段。

try {
   file = new FileInputStream(fileName);
   x = (byte) file.read();
} catch (IOException i) {
   i.printStackTrace();
   return -1;
} catch (FileNotFoundException f) // Not valid! {
   f.printStackTrace();
   return -1;
}

捕获多种异常

从 Java 7 开始,您可以使用单个 catch 块处理多个异常,此功能简化了代码。这是你的做法 -

catch (IOException|FileNotFoundException ex) {
   logger.log(ex);
   throw ex;

投掷/投掷关键字

如果方法不处理已检查的异常,则该方法必须使用 throws 声明它 关键词。 throws 关键字出现在方法签名的末尾。

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

尝试理解 throws 和 throw 关键字的区别,throws 用于推迟检查异常的处理并抛出 用于显式调用异常。

以下方法声明它抛出一个 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
}

最后的方块

finally 块跟在 try 块或 catch 块之后。 finally 代码块总是执行,无论是否发生异常。

使用 finally 块允许您运行任何您想要执行的清理类型语句,无论受保护的代码中发生什么。

finally 块出现在 catch 块的末尾,语法如下 -

语法

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}finally {
   // The finally block always executes.
}

示例

现场演示
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

注意以下 -

try-with-resources

通常,当我们使用流、连接等任何资源时,我们必须使用 finally 块显式关闭它们。在下面的程序中,我们使用 FileReader 从文件中读取数据 我们正在使用 finally 块关闭它。

示例

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]) {
      FileReader fr = null;		
      try {
         File file = new File("file.txt");
         fr = new FileReader(file); char [] a = new char[50];
         fr.read(a);   // reads the content to the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }finally {
         try {
            fr.close();
         } catch (IOException ex) {		
            ex.printStackTrace();
         }
      }
   }
}

尝试资源 ,也称为自动资源管理 , 是 Java 7 中引入的一种新的异常处理机制,它会自动关闭 try catch 块中使用的资源。

要使用该语句,您只需在括号内声明所需的资源,创建的资源将在块的末尾自动关闭。以下是try-with-resources语句的语法。

语法

try(FileReader fr = new FileReader("file path")) {
   // use the resource
   } catch () {
      // body of catch 
   }
}

以下是使用 try-with-resources 语句读取文件中数据的程序。

示例

import java.io.FileReader;
import java.io.IOException;

public class Try_withDemo {

   public static void main(String args[]) {
      try(FileReader fr = new FileReader("E://file.txt")) {
         char [] a = new char[50];
         fr.read(a);   // reads the contentto the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

在使用 try-with-resources 语句时要牢记以下几点。

用户定义的异常

您可以在 Java 中创建自己的异常。在编写自己的异常类时请记住以下几点 -

我们可以定义我们自己的异常类如下 -

class MyException extends Exception {
}

您只需要扩展预定义的 Exception 类来创建您自己的异常。这些被认为是检查异常。以下 InsufficientFundsException class 是一个用户定义的异常,它扩展了 Exception 类,使其成为受检异常。异常类与任何其他类一样,包含有用的字段和方法。

示例

// File Name InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception {
   private double amount;
   
   public InsufficientFundsException(double amount) {
      this.amount = amount;
   }
   
   public double getAmount() {
      return amount;
   }
}

为了演示如何使用我们的用户定义的异常,下面的 CheckingAccount 类包含一个抛出 InsufficientFundsException 的withdraw() 方法。

// File Name CheckingAccount.java
import java.io.*;

public class CheckingAccount {
   private double balance;
   private int number;
   
   public CheckingAccount(int number) {
      this.number = number;
   }
   
   public void deposit(double amount) {
      balance += amount;
   }
   
   public void withdraw(double amount) throws InsufficientFundsException {
      if(amount <= balance) {
         balance -= amount;
      }else {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
   
   public double getBalance() {
      return balance;
   }
   
   public int getNumber() {
      return number;
   }
}

下面的BankDemo程序演示了调用CheckingAccount的deposit()和withdraw()方法。

// File Name BankDemo.java
public class BankDemo {

   public static void main(String [] args) {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      
      try {
         System.out.println("\nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing $600...");
         c.withdraw(600.00);
      } catch (InsufficientFundsException e) {
         System.out.println("Sorry, but you are short $" + e.getAmount());
         e.printStackTrace();
      }
   }
}

编译以上三个文件并运行 BankDemo。这将产生以下结果 -

输出

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
         at CheckingAccount.withdraw(CheckingAccount.java:25)
         at BankDemo.main(BankDemo.java:13)

常见异常

在 Java 中,可以定义 Exceptions 和 Errors 两类。


java

  1. Java 运算符
  2. Java 评论
  3. Java for-each 循环
  4. Java 字符串
  5. Java 接口
  6. Java 匿名类
  7. Java 异常处理
  8. Java 抛出和抛出
  9. Java 捕获多个异常
  10. Java try-with-resources
  11. Java 注释
  12. Java 断言