JavaRush /Java Blog /Random-KO /Java의 예외(Java Exception)

Java의 예외(Java Exception)

Random-KO 그룹에 게시되었습니다
일상생활을 하다 보면, 우리가 계획하지 않은 상황이 발생할 때가 있습니다. 예를 들어, 아침에 일어나서 휴대폰 충전기를 찾았지만 충전기가 없습니다. 당신은 세수를 하러 화장실에 갑니다. 물이 꺼져 있습니다. 차에 탔는데 시동이 안 걸려요. 그러나 사람은 그러한 예상치 못한 상황에 아주 쉽게 대처할 수 있습니다. 우리는 이 기사에서 Java 프로그램이 이를 어떻게 처리하는지 알아내려고 노력할 것입니다.

예외란 무엇입니까?

프로그래밍 세계에서는 프로그램 실행 중에 발생하는 오류나 예상치 못한 상황을 예외라고 합니다. 프로그램에서는 잘못된 사용자 작업, 디스크에 필요한 리소스 부족, 네트워크를 통한 서버 연결 끊김 등으로 인해 예외가 발생할 수 있습니다. 프로그램 실행 중 예외는 프로그래밍 오류나 API의 잘못된 사용으로 인해 발생할 수도 있습니다. 우리 세계와는 달리 프로그램은 그러한 상황에서 무엇을 해야 할지 명확하게 알고 있어야 합니다. Java는 이러한 목적을 위해 예외 메커니즘을 제공합니다.

try, catch, finally, throws 키워드에 대해 간략히 설명합니다.

Java의 예외 처리는 프로그램에서 다음 키워드의 사용을 기반으로 합니다.
  • try - 예외가 발생할 수 있는 코드 블록을 정의합니다.
  • catch – 예외가 처리되는 코드 블록을 정의합니다.
  • finally – 선택 사항이지만 존재하는 경우 try 블록의 결과에 관계없이 실행되는 코드 블록을 정의합니다.
이러한 키워드는 프로그램 코드에서 특별한 처리 구성을 생성하는 데 사용됩니다. try{}catch, try{}catch{}finally, try{}finally{}.
  • throw – 예외를 발생시키는 데 사용됩니다.
  • throws – 메소드가 예외를 던질 수 있음을 경고하기 위해 메소드 시그니처에 사용됩니다.
Java 프로그램에서 키워드를 사용하는 예:
//method reads a string from the keyboard

public String input() throws MyException {//warn with throws,
// that the method can throw MyException
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String s = null;
// in the try block we enclose the code in which an exception can occur, in this
// if the compiler tells us that the readLine() method of the class
// BufferedReader may throw an I/O exception
    try {
        s = reader.readLine();
// in the catch block we enclose the code for handling the IOException exception
    } catch (IOException e) {
        System.out.println(e.getMessage());
// close the read stream in the finally block
    } finally {
// when closing the stream, an exception is also possible, for example, if it was not opened, so we “wrap” the code in a try block
        try {
            reader.close();
// write exception handling when closing the read stream
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    if (s.equals("")) {
// we decided that an empty string could disrupt the work of our program in the future, for example, on the result of this method, we need to call the substring(1,2) method, so we are forced to interrupt the program execution with the generation of our exception type MyException using throw
        throw new MyException("String can not be empty!");
    }
    return s;
}

예외 메커니즘이 필요한 이유는 무엇입니까?

실제 사례를 살펴보겠습니다. 제한된 적재 능력을 갖춘 비상 다리가 있는 고속도로 구간이 있다고 상상해 보십시오. 다리의 운반 능력을 초과하는 질량을 가진 차량이 다리를 가로질러 주행하는 경우 차량이 붕괴될 수 있으며 운전자의 상황은 약간 예외적인 상황이 될 수 있습니다. 이를 방지하기 위해 도로공사에서는 사전에 도로에 경고표지판을 설치합니다. 경고 표지판을 보면서 자동차 운전자는 자신의 자동차 무게와 다리에서 운전할 수 있는 무게를 비교할 것입니다. 이를 초과하면 우회하게 됩니다. 도로 서비스의 조치 덕분에 트럭 운전자는 먼저 경로를 미리 변경할 수 있는 기회를 얻었고, 두 번째로 주요 경로의 위험에 대해 경고를 받았으며, 마지막으로 사용 불가능에 대해 경고를 받았습니다. 특정 조건 하에서 다리.
Исключения в Java - 2
프로그램에서 예외가 계속 발생하도록 방지하고 해결하는 능력은 Java에서 예외를 사용하는 이유 중 하나입니다. 또한 예외 메커니즘을 사용하면 들어오는 데이터의 유효성을 검사(확인)하여 사용자가 작성한 코드(프로그래밍 인터페이스)를 오용으로부터 보호할 수 있습니다. 이제 잠시 교통경찰이 되어 봅시다. 먼저, 운전자가 문제를 일으킬 수 있는 장소를 알아야 합니다. 둘째, 경고표지판을 준비하고 설치해야 합니다. 마지막으로, 주요 경로에 위험이 발생할 경우를 대비하여 우회 경로를 제공해야 합니다. Java에서는 예외 메커니즘이 비슷한 방식으로 작동합니다. 프로그램 개발 단계에서는 try{} 블록을 사용하여 코드의 위험한 부분을 예외로부터 "보호"하고, catch{} 블록을 사용하여 "백업" 경로를 제공하며, finally{} 블록에서 실행되는 코드를 작성합니다. 어떤 결과를 위한 프로그램입니다. "비상 경로"를 제공할 수 없거나 의도적으로 사용자에게 선택권을 맡기고 싶은 경우, 최소한 사용자에게 위험에 대해 경고해야 합니다. 왜? 도중에 경고 표지판 하나도 보지 않고는 운전할 수 없는 비상 교량에 도착한 운전자의 분노를 상상해 보십시오! 프로그래밍에서 클래스와 메서드를 작성할 때 다른 개발자가 프로그램에서 사용하는 컨텍스트를 항상 예측할 수는 없으므로 예외를 해결하는 100% 올바른 방법을 예측할 수는 없습니다. 동시에 사용자에게 예외 가능성에 대해 경고하는 것이 좋습니다. Java의 예외 메커니즘을 사용하면 throw를 사용하여 이 작업을 수행할 수 있습니다. 기본적으로 예외를 발생시키는 메서드의 일반적인 동작을 선언하여 Java에서 예외를 처리하는 코드를 작성하는 것은 메서드 사용자의 몫입니다.

"문제" 경고

메서드에서 예외를 처리할 계획은 없지만 메서드 사용자에게 가능한 예외 상황에 대해 경고하려는 경우 throws 키워드를 사용하세요. 메서드 시그니처의 이 키워드는 특정 조건에서 메서드가 예외를 throw할 수 있음을 의미합니다. 이 경고는 메소드 인터페이스의 일부이며 사용자에게 예외 핸들러의 구현을 사용자 정의할 수 있는 권한을 제공합니다. throw 후에는 throw되는 예외 유형을 나타냅니다. 이는 일반적으로 Java Exception 클래스의 자손입니다 . Java는 객체 지향 언어이므로 Java의 모든 예외는 객체입니다.
Исключения в Java - 3

Java 예외 계층

프로그램 실행 중에 오류가 발생하면 JVM 런타임은 Java 예외 계층 구조(공통 "조상"에서 상속된 가능한 예외 집합인 Throwable 클래스)에서 필요한 유형의 객체를 생성합니다. 프로그램에서 발생하는 예외 상황은 두 그룹으로 나눌 수 있습니다.
  1. 프로그램의 정상적인 작동을 더 이상 복구할 수 없는 상황
  2. 회복이 가능합니다.
첫 번째 그룹에는 Error 클래스에서 상속된 예외가 발생하는 상황이 포함됩니다 . JVM 오류, 메모리 오버플로 또는 시스템 충돌로 인해 프로그램 실행 중에 발생하는 오류입니다. 이는 일반적으로 소프트웨어를 사용하여 해결할 수 없는 심각한 문제를 나타냅니다. Java에서 이러한 유형의 예외는 컴파일 단계에서 확인되지 않은 것으로 분류됩니다. 이 그룹에는 RuntimeException(예외, 프로그램 실행 중에 JVM에서 생성되는 Exception 클래스의 상속자)도 포함됩니다. 프로그래밍 오류로 인해 발생하는 경우가 많습니다. 이러한 예외는 컴파일 타임에도 확인되지 않으므로 이를 처리하기 위한 코드를 작성할 필요가 없습니다. 두 번째 그룹에는 프로그램 작성 단계에서 예측되고 처리 코드를 작성해야 하는 예외 상황이 포함됩니다. 이러한 예외는 확인됩니다. 예외를 처리할 때 Java 개발자의 작업 중 대부분은 이러한 상황을 처리하는 것입니다.

예외 생성

프로그램 실행 중에 JVM에 의해 또는 수동으로 throw 문을 사용하여 예외가 발생합니다 . 이는 메모리에 예외 객체를 생성하고 JVM 예외 처리기가 예외를 처리할 방법을 찾으려고 시도하는 동안 기본 프로그램 코드의 실행을 중단합니다.

예외 처리

Java에서 예외 처리를 제공하는 코드 블록 생성은 프로그램에서 try{}catch, try{}catch{}finally, try{}finally{} 구문을 사용하여 수행됩니다.
Исключения в Java - 4
try 블록에서 예외가 발생하면 다음 catch 블록에서 예외 처리기를 찾습니다. catch에 이러한 유형의 예외에 대한 처리기가 포함되어 있으면 제어가 전달됩니다. 그렇지 않은 경우 JVM은 적절한 catch를 찾을 때까지 메서드 호출 체인에서 해당 예외 유형에 대한 핸들러를 찾습니다. catch 블록이 실행된 후 선택적인 finally 블록으로 제어가 전달됩니다 . 적합한 catch 블록이 발견되지 않으면 JVM은 프로그램 실행을 중지하고 이전에 finally 블록 코드(있는 경우)를 실행한 메서드 호출 스택(스택 추적)을 표시 합니다 . 예외 처리 예:
public class Print {

     void print(String s) {
        if (s == null) {
            throw new NullPointerException("Exception: s is null!");
        }
        System.out.println("Inside method print: " + s);
    }

    public static void main(String[] args) {
        Print print = new Print();
        List list= Arrays.asList("first step", null, "second step");

        for (String s:list) {
            try {
                print.print(s);
            }
            catch (NullPointerException e) {
                System.out.println(e.getMessage());
                System.out.println("Exception was processed. Program continues");
            }
            finally {
                System.out.println("Inside bloсk finally");
            }
            System.out.println("Go program....");
            System.out.println("-----------------");
        }

    }
    }
주요 방법 의 결과 :
Inside method print: first step
Inside bloсk finally
Go program....
-----------------
Exception: s is null!
Exception was processed. Program continues
Inside bloсk finally
Go program....
-----------------
Inside method print: second step
Inside bloсk finally
Go program....
-----------------
블록은 finally일반적으로 try 블록에서 열린 스트림을 닫거나 리소스를 해제하는 데 사용됩니다. 그러나 프로그램을 작성할 때 모든 리소스의 종료를 항상 추적할 수 있는 것은 아닙니다. 우리의 삶을 더 쉽게 만들기 위해 Java 개발자는 try-with-resourcestry 블록에서 열린 리소스를 자동으로 닫는 구성을 제공했습니다. 첫 번째 예는 다음과 같이 다시 작성할 수 있습니다 try-with-resources.
public String input() throws MyException {
    String s = null;
    try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){
        s = reader.readLine();
   } catch (IOException e) {
       System.out.println(e.getMessage());
   }
    if (s.equals("")){
        throw new MyException ("String can not be empty!");
    }
    return s;
}
버전 7부터 Java의 기능 덕분에 다양한 유형의 예외 포착을 단일 블록에 결합하여 코드를 더 간결하고 읽기 쉽게 만들 수 있습니다. 예를 들어:
public String input() {
    String s = null;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
        s = reader.readLine();
        if (s.equals("")) {
            throw new MyException("String can not be empty!");
        }
    } catch (IOException | MyException e) {
        System.out.println(e.getMessage());
    }
    return s;
}

결과

Java에서 예외를 사용하면 "백업" 경로를 사용하여 프로그램의 내결함성을 높이고, 캐치 블록을 사용하여 예외 처리 코드에서 기본 코드의 논리를 분리하고, 위임할 수 있는 기회도 제공합니다. throw를 사용하여 코드 사용자에 대한 예외 처리.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION