자바 예외 처리


예외는 프로그램의 일부 오류이지만 모든 오류가 예외는 아니며 때로는 오류를 피할 수 있습니다.

예를 들어 코드에 세미콜론이 없으면 실행 결과 java.lang.Error가 발생합니다. System.out.println(11/0)을 사용하면 0을 사용하기 때문입니다. 제수의 경우 java.lang.ArithmeticException 예외가 발생합니다.

비정상에는 여러 가지 이유가 있으며 일반적으로 다음 범주를 포함합니다.

  •                   사용자가 불법적인 데이터를 입력했습니다.

  •               열려는 파일이 존재하지 않습니다.

  •               네트워크 통신 중에 연결이 중단되거나 JVM 메모리가 오버플로됩니다.

이러한 예외 중 일부는 사용자 오류로 인해 발생하고 일부는 프로그램 오류로 인해 발생하며 다른 일부는 물리적 오류로 인해 발생합니다. -

Java 예외 처리가 어떻게 작동하는지 이해하려면 다음 세 가지 유형의 예외를 마스터해야 합니다.

  • Checked 예외: 가장 대표적인 Checked 예외는 사용자 오류나 문제로 인해 발생하는 예외입니다. 프로그래머는 예측할 수 없습니다. 예를 들어, 존재하지 않는 파일을 열려고 하면 예외가 발생합니다. 이러한 예외는 컴파일 타임에 단순히 무시할 수 없습니다.

  • 런타임 예외: 런타임 예외는 프로그래머가 피할 수 있는 예외입니다. 확인된 예외와 달리 런타임 예외는 컴파일 타임에 무시될 수 있습니다.

  • 오류: 오류는 예외가 아니지만 프로그래머의 통제를 벗어난 문제입니다. 코드에서는 오류가 무시되는 경우가 많습니다. 예를 들어 스택이 오버플로되면 컴파일 중에 확인할 수 없는 오류가 발생합니다.


Exception 클래스 계층

모든 예외 클래스는 java.lang.Exception 클래스에서 상속된 하위 클래스입니다.

Exception 클래스는 Throwable 클래스의 하위 클래스입니다. Exception 클래스 외에도 Throwable에는 Error 하위 클래스도 있습니다.

Java 프로그램은 일반적으로 오류를 포착하지 않습니다. 오류는 일반적으로 심각한 오류가 발생할 때 발생하며 Java 프로그램 처리 범위를 벗어납니다.

Error는 런타임 환경에서 발생하는 오류를 나타내는 데 사용됩니다.

예를 들어 JVM 메모리 오버플로가 있습니다. 일반적으로 프로그램은 오류로부터 복구되지 않습니다.

예외 클래스에는 IOException 클래스와 RuntimeException 클래스라는 두 가지 주요 하위 클래스가 있습니다.

12-130Q1234I6223.jpg

Java 내장 클래스(다음에 설명)에는 가장 일반적으로 사용되는 확인된 예외와 확인되지 않은 예외가 있습니다.


Java 내장 예외 클래스

Java 언어는 java.lang 표준 패키지에 일부 예외 클래스를 정의합니다.

표준 런타임 예외 클래스의 하위 클래스는 가장 일반적인 예외 클래스입니다. java.lang 패키지는 기본적으로 모든 Java 프로그램에 로드되므로 런타임 예외 클래스에서 상속된 대부분의 예외를 직접 사용할 수 있습니다.

Java는 각 클래스 라이브러리를 기반으로 몇 가지 다른 예외도 정의합니다. 다음 표에는 Java의 확인되지 않은 예외가 나열되어 있습니다.

                      NumberFormatException​​​​​​​ 이 예외는 애플리케이션이 문자열을 숫자 유형으로 변환하려고 시도하지만 문자열을 적절한 형식으로 변환할 수 없는 경우 발생합니다.                 SecurityException
ExceptionDescription
ArithmeticException​​​​​​​ 이 예외는 비정상적인 작업 조건이 발생할 때 발생합니다. 예를 들어 정수가 "0으로 나누어지면" 이 클래스의 인스턴스가 발생합니다.
                ArrayIndexOutOfBoundsException​​​​​​ 잘못된 인덱스가 있는 배열에 액세스할 때 예외가 발생했습니다. 인덱스가 음수이거나 배열 크기보다 크거나 같으면 잘못된 인덱스입니다.
                ArrayStoreException                 잘못된 유형의 객체를 객체 배열에 저장하려고 할 때 예외가 발생했습니다.
                ClassCastException                   이 예외는 인스턴스가 아닌 하위 클래스에 객체를 캐스팅하려고 시도할 때 발생합니다.
                IllegalArgumentException                   발생한 예외는 불법적이거나 잘못된 매개변수가 메서드에 전달되었음을 나타냅니다.
                IllegalMonitorStateException                 던져진 예외는 스레드가 개체의 모니터에서 기다리려고 시도했거나 자체적으로 모니터를 지정하지 않고 개체의 모니터에서 기다리고 있는 다른 스레드에 알리려고 시도했음을 나타냅니다.
                IllegalStateException                 불법적이거나 부적절한 시간에 메소드가 호출될 때 생성되는 신호입니다. 즉, Java 환경이나 Java 애플리케이션이 요청된 작업에 적합한 상태가 아닙니다.
                IllegalThreadStateException                 스레드가 요청된 작업에 필요한 적절한 상태가 아닌 경우 예외가 발생합니다.
                IndexOutOfBoundsException​​​​​​​ 정렬 인덱스(예: 배열, 문자열 또는 벡터의 정렬)가 범위를 벗어났음을 나타낼 때 발생합니다.
                NegativeArraySizeException                   이 예외는 애플리케이션이 음수 크기의 배열을 생성하려고 시도하는 경우 발생합니다.
                NullPointerException​​​​​​​ 이 예외는 애플리케이션이 객체가 예상되는 곳에 null을 사용하려고 시도할 때 발생합니다. null 时,抛出该异常
                    NumberFormatException                    当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
                    SecurityException                    由安全管理器抛出的异常,指示存在安全侵犯。
                    StringIndexOutOfBoundsException                    此异常由 String
🎜​​​​​​ 보안 위반을 나타내기 위해 보안 관리자가 던진 예외입니다. 🎜🎜🎜🎜                 StringIndexOutOfBoundsException 🎜🎜                     이 예외는 String 메서드에 의해 발생하며 인덱스가 음수이거나 문자열 크기를 초과함을 나타냅니다. 🎜🎜🎜🎜                 UnsupportedOperationException🎜🎜​​​​​​​ 이 예외는 요청한 작업이 지원되지 않을 때 발생합니다. 🎜🎜🎜🎜

다음 표에는 java.lang 패키지에서 Java가 정의한 확인된 예외 클래스가 나열되어 있습니다.

                IllegalAccessException                 이 예외는 클래스에 대한 액세스가 거부될 때 발생합니다.                 InstantiationException​​​​​​​ Class 클래스의 newInstance 메서드를 사용하여 클래스의 인스턴스를 생성하려고 시도했지만 지정된 클래스 객체가 인터페이스 또는 인스턴스이기 때문에 인스턴스화할 수 없는 경우 추상 클래스, throws 이 예외가 발생합니다.                 InterruptedException                 이 예외는 스레드가 다른 스레드에 의해 중단될 때 발생합니다.                 NoSuchFieldException
ExceptionDescription
ClassNotFoundException                            애플리케이션이 클래스를 로드하려고 하면 해당 클래스를 찾을 수 없으며 이 예외가 발생합니다.
                CloneNotSupportedException                 이 예외는 개체를 복제하기 위해 Object 클래스의 clone 메서드가 호출되었지만 개체의 클래스가 Cloneable 인터페이스를 구현할 수 없는 경우 발생합니다. Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
                    IllegalAccessException                    拒绝访问一个类的时候,抛出该异常。
                    InstantiationException                    当试图使用 Class 类中的 newInstance
🎜                 요청한 변수가 존재하지 않습니다🎜🎜🎜🎜​​​​​​​​ NoSuchMethodException🎜🎜                 요청한 방법이 존재하지 않습니다🎜🎜🎜🎜

예외 메소드

다음 목록은 Throwable 클래스의 주요 메소드입니다.

일련 번호메서드 및 설명
1공개 문자열 getMessage()
발생한 예외에 대한 자세한 정보를 반환합니다. 이 메시지는 Throwable 클래스의 생성자에서 초기화됩니다.
                2공용 Throwable getCause()
예외의 원인을 나타내는 Throwable 객체를 반환합니다.
                3공개 문자열 toString()
getMessage()의 결과를 사용하여 연결된 클래스 이름을 반환합니다.
                4public void printStackTrace()
toString() 결과와 스택 수준을 오류 출력 스트림인 System.err에 인쇄합니다.
                5공개 StackTraceElement [] getStackTrace()
스택 수준을 포함하는 배열을 반환합니다. 인덱스 0의 요소는 스택의 맨 위를 나타내고, 마지막 요소는 메서드 호출 스택의 맨 아래를 나타냅니다.
                6공개 던질 수 있는 fillInStackTrace()
Throwable 개체 스택 수준을 현재 호출 스택 수준으로 채워 스택 수준의 이전 정보에 추가합니다.

예외 포착

try 및 catch 키워드를 사용하여 예외를 포착하세요. Try/catch 코드 블록은 예외가 발생할 수 있는 위치에 배치됩니다.

try/catch 코드 블록의 코드를 가드 코드라고 합니다. try/catch를 사용하는 구문은 다음과 같습니다.

try
{
   // 程序代码
}catch(ExceptionName e1)
{
   //Catch 块
}

Catch 문에는 catch할 예외 유형에 대한 선언이 포함되어 있습니다. 보호된 코드 블록에서 예외가 발생하면 try 다음에 오는 catch 블록을 확인합니다.

발생한 예외가 catch 블록에 포함되어 있으면 예외가 catch 블록으로 전달되는데, 이는 메서드에 매개변수를 전달하는 것과 같습니다.

Example

다음 예제에서는 두 개의 요소가 있는 배열을 선언합니다. 코드가 배열의 세 번째 요소에 액세스하려고 하면 예외가 발생합니다.

// 文件名 : 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

다중 캡처 블록

try 코드 블록 뒤에 여러 캐치 코드 블록이 오는 것을 다중 캡처라고 합니다.

다중 catch 블록의 구문은 다음과 같습니다.

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

위 코드 조각에는 3개의 catch 블록이 포함되어 있습니다.

try 문 뒤에 catch 블록을 원하는 만큼 추가할 수 있습니다.

보호된 코드에서 예외가 발생하면 첫 번째 catch 블록에 예외가 발생합니다.

발생한 예외의 데이터 유형이 ExceptionType1과 일치하면 여기에서 포착됩니다.

일치하는 항목이 없으면 두 번째 catch 블록으로 전달됩니다.

이는 예외가 포착되거나 모든 포착 블록을 통과할 때까지 계속됩니다.

Example

이 예에서는 여러 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;
}

throws/throw 키워드:

메서드가 확인된 예외를 포착하지 못하는 경우 해당 메서드는 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
}

finally 키워드

finally 키워드는 try 코드 블록 이후에 실행되는 코드 블록을 생성하는 데 사용됩니다.

예외 발생 여부에 관계없이 finally 코드 블록의 코드는 항상 실행됩니다.

finally 코드 블록에서는 정리 문 및 기타 정리 문을 실행할 수 있습니다.

마지막으로 코드 블록은 catch 코드 블록 끝에 나타나며 구문은 다음과 같습니다.

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

Example

 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 블록 사이에는 코드를 추가할 수 없습니다.


사용자 정의 예외 선언

Java에서는 예외를 사용자 정의할 수 있습니다. 자신만의 예외 클래스를 작성할 때 염두에 두어야 할 몇 가지 사항이 있습니다.

  •               모든 예외는 Throwable의 하위 클래스여야 합니다.

  •               확인된 예외 클래스를 작성하려면 Exception 클래스를 상속해야 합니다.

  •               런타임 예외 클래스를 작성하려면 RuntimeException 클래스를 상속해야 합니다.

다음과 같이 자신만의 예외 클래스를 정의할 수 있습니다.

class MyException extends Exception{
}

Exception 클래스만 상속하여 생성된 예외 클래스는 확인된 예외 클래스입니다.

다음 InsufficientFundsException 클래스는 Exception을 상속하는 사용자 정의 예외 클래스입니다.

예외 클래스는 변수와 메서드를 포함하는 다른 클래스와 같습니다.

// 文件名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 예외를 발생시킵니다.

// 文件名称 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 클래스의 예금() 및 인출() 메서드를 호출하는 방법을 보여줍니다.

//文件名称 BankDemo.java
public class BankDemo
{
   public static void main(String [] args)
   {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing 0...");
      c.deposit(500.00);
      try
      {
         System.out.println("\nWithdrawing 0...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing 0...");
         c.withdraw(600.00);
      }catch(InsufficientFundsException e)
      {
         System.out.println("Sorry, but you are short $"
                                  + e.getAmount());
         e.printStackTrace();
      }
    }
}

위 세 파일을 컴파일하고 BankDemo 프로그램을 실행하면 다음과 같습니다.

Depositing 0...

Withdrawing 0...

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

일반 예외

Java에서는 두 가지 유형의 예외와 오류가 정의됩니다.

  • JVM(JavaVirtual Machine)예외: JVM에서 발생한 예외 또는 오류입니다. 예: NullPointerException 클래스, ArrayIndexOutOfBoundsException 클래스, ClassCastException 클래스.

  • 프로그램 수준 예외: 프로그램 또는 API 프로그램에서 발생한 예외입니다. 예를 들어 IllegalArgumentException 클래스, IllegalStateException 클래스입니다.