1. 예외

>

마침내 프로그래머들은 오류 처리를 표준화하고 자동화할 생각을 했습니다. 이것은 예외가 발명되었을 때 일어났습니다. 이제 예외 메커니즘이 예외 상황의 80%를 처리합니다.

만약 어떤 학자가 예외를 내놓았다면 그것은 아마도 그의 박사학위 논문의 주제였을 것이다. 프로그래머가 그것을 생각해 냈다면 동료로부터 다정하게 등을 토닥여 주었을 것입니다. "괜찮아 보여요, 친구."

자바 프로그램에서 division by 와 같은 오류가 발생하면 0몇 가지 놀라운 일이 발생합니다.

1단계

발생한 오류에 대한 정보를 포함하는 특수 예외 개체가 생성됩니다.

Java의 모든 것은 객체이며 예외는 예외가 아닙니다 🙂 예외 객체에는 자체 클래스가 있으며 일반 클래스와 구별되는 유일한 것은 클래스를 상속한다는 것입니다 Throwable.

2단계

예외 객체는 "throw"됩니다. 아마도 여기의 표현이 더 나을 수 있습니다. "예외 발생"은 화재 경보를 울리거나 "DEFCON 1" 경보를 울리는 것과 비슷합니다.

Java 머신에 예외가 발생하면 프로그램의 정상 작동이 중지되고 "긴급 프로토콜"이 시작됩니다.

3단계

예외가 발생한 메서드는 즉시 종료됩니다. 예외는 즉시 종료되는 호출 메서드로 전달됩니다. 그리고 메서드가 종료될 때까지 체인 아래로 계속됩니다 main. 메서드가 종료 되면 main프로그램도 종료됩니다.

예:

암호 콘솔 출력
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Your attention, please! Preparing for the end of the world");
      endTheWorld();
      System.out.println("The world ended successfully");
   }

   public static void endTheWorld()
   {
      System.out.println("We're doing something important");
      doSomeWork(0);
      System.out.println("Everything is working well");
   }

   public static void doSomeWork(int n)
   {
      System.out.println("Nothing terrible will happen: " + n);
      System.out.println(2 / n);
      System.out.println("Nothing terrible happened: " + n);
   }
}
Your attention, please! Preparing for the end of the world
We're doing something important
Nothing terrible will happen: 0

20행에서 예외가 발생합니다: 0으로 나누기. Java 머신은 즉시 예외 ( ArithmeticException객체)를 생성하고 이를 메서드에 "던집니다".

메서드 divide()는 즉시 종료되므로 아무 일도 일어나지 않았습니다: 0 문자열을 볼 수 없습니다. 프로그램이 메서드로 돌아가고 endTheWorld()상황이 반복됩니다. 시스템에 처리되지 않은 예외가 있으며 이는 메서드 endTheWorld()도 비정상적으로 종료됨을 의미합니다. 그런 다음 main메서드가 종료되고 프로그램이 중지됩니다.

이러한 예외의 목적은 무엇입니까? 글쎄요, 특정 유형의 예외를 포착하는 코드를 작성 하고 예외 상황을 처리하는 고유한 논리를 작성할 수 있습니다.


2. 캐치 예외:try-catch

Java에는 이러한 비정상적인 메서드 종료를 중지할 수 있는 예외 포착 메커니즘이 있습니다. 다음과 같이 보입니다.

try
{
   // Code where an exception might occur
}
catch(ExceptionType name)
{
   // Exception handling code
}

이 구조를 블록이라고 합니다 try-catch.

예외가 발생할 수 있는 코드는 단어 앞에 중괄호로 묶여 있습니다 try.

중괄호 뒤에는 catch키워드가 있고 괄호 안에는 예외 변수 선언이 있습니다 . 그 다음에는 지정된 유형의 예외가 발생하는 경우 실행될 코드를 감싸는 중괄호가 옵니다 .

" 기본 코드 " 실행 중에 예외가 발생하지 않으면 catch 블록 내부의 코드가 실행되지 않습니다. 예외가 발생하면 예외가 발생합니다(발생한 예외의 유형이 괄호 안의 변수 유형과 동일한 경우).

예:

암호 콘솔 출력
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Hadron Collider launched");

      try
      {
         launchHadronCollider(1);
         launchHadronCollider(0);
      }
      catch(Exception e)
      {
         System.out.println("Error! Caught an exception");
         System.out.println("The planet was sucked into a black hole!");
      }

      System.out.println("The Hadron Collider stopped");
   }

   public static void launchHadronCollider(int n)
   {
      System.out.println("Everything is working well: " + n);
      System.out.println(2/n);
      System.out.println("There are no problems: " + n);
   }
}
Hadron Collider launched
Everything is working fine: 1
2
There are no problems: 1
Everything is working fine: 0
Error! Caught an exception
The planet has been sucked into a black hole!
The Hadron Collider is stopped


3. 다중 catch블록

다중 catch 블록

이론적으로 모든 종류의 예외는 코드 블록에서 발생할 수 있습니다. 일부는 이런 식으로 처리하고 다른 일부는 다른 방식으로 처리하고 나머지는 전혀 처리하지 않기로 결정합니다.

Java 개발자는 당신을 돕기로 결정하고 블록 catch뒤에 하나가 아니라 많은 블록을 작성하도록 허용했습니다 try.

try
{
   // Code where an exception might occur
}
catch (ExceptionType1 name1)
{
   // Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
   // Code for handling ExceptionType2
}
   catch (ExceptionType3 name3)
{
   // Code for handling ExceptionType3
}

예:

암호 콘솔 출력
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Start of main method");
      try
      {
         calculate(0);
      }
      catch (ArithmeticException e)
      {
         System.out.println("Division by 0");
      }
      catch(Exception e)
      {
         System.out.println("Caught some kind of exception");
      }

      System.out.println("End of main method");
   }

   public static void calculate(int n)
   {
      System.out.println("Start of calculate method: " + n);
      System.out.println(2/n);
      System.out.println("End of calculate method: " + n);
   }
}
Start of main method
Start of calculate method: 0
Division by 0
End of main method


catch4. 블록 의 순서

블록 에서 발생하는 예외는 try단일 catch블록에서만 포착할 수 있습니다. 여러 블록의 코드가 실행되는 예외 처리 상황이 있을 수 없습니다 .catch

그러나 블록의 순서가 중요합니다.

여러 블록에서 예외를 포착할 수 있는 상황이 있을 수 있습니다. 이 경우 먼저 발생하는 catchtry 블록( 블록에 가장 가까운 블록)이 예외를 catch합니다.

여러 catch 블록이 동일한 예외를 catch할 수 있는 상황을 어떻게 가질 수 있습니까?

모든 예외는 단일 상속 계층 구조에 속합니다. 다이어그램을 참조하세요.

예외 계층

개체 는 유형이 다음 과 같은ArithmeticException 변수에 할당될 수 있습니다 .ArithmeticException RuntimeExceptionExceptionThrowable

상속과 조상 클래스에 대한 자세한 내용은 레벨 21에서 다루겠습니다.

이 코드는 잘 컴파일됩니다.

상속의 이점:
ArithmeticException ae    = new ArithmeticException();
RuntimeException runtime  = new ArithmeticException();
Exception exception       = new ArithmeticException();
Throwable trwbl           = new ArithmeticException();

ArithmeticException따라서 위 의 4개 블록 중 하나로 잡을 수 있습니다 catch.

예 1:

암호 콘솔 출력
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Start of main method");
      try
      {
         calculate(0);
      }
      catch(ArithmeticException e)
      {
         System.out.println("Division by 0");
      }
      catch(Exception e)
      {
         System.out.println("Caught some kind of exception");
      }

      System.out.println("End of main method");
   }

   public static void calculate(int n)
   {
      System.out.println("Start of calculate method: " + n);
      System.out.println(2/n);
      System.out.println("End of calculate method: " + n);
   }
}
Start of main method
Start of calculate method: 0
Division by 0
End of main method

이 예에서 the는 and 블록 ArithmeticException모두에 의해 포착될 수 있습니다 . 블록에 가장 가까운 블록인 첫 번째 블록 에 의해 잡힙니다 .catch (Exception e)catch (ArithmeticException e)trycatch

catch놀라움을 피하려면 거의 모든 예외를 포착할 수 있는 블록을 블록 목록의 끝 부분에 배치하는 것이 가장 좋습니다 .catch

유형 은 일반적으로 Java에서 가능한 모든 예외를 포착Throwable 할 수 있습니다 . 첫 번째 블록에 넣으면 코드가 컴파일되지 않습니다. 컴파일러는 도달할 수 없는 코드 블록이 있음을 알고 있기 때문입니다.catch