JavaRush /Java Blog /Random-KO /자바의 예외
Roman
레벨 33

자바의 예외

Random-KO 그룹에 게시되었습니다
"예외"라는 주제를 접했을 때 모든 것이 어떻게 작동하는지 자세히 이해하기 위해 인터넷의 다양한 구석에서 답을 찾아야 하는 많은 질문이 생겼습니다. 그 결과, 이 현상을 막 접한 초보자들이 더 이해하기 쉽도록 나만의 설명을 정리했습니다. Java의 예외 - 1컴퓨터에서 인터럽트는 즉각적인 응답이 필요한 이벤트가 발생하고 있음을 프로세서에 보내는 신호입니다. 인터럽트 신호는 프로세서가 잠시 후에 계속할 수 있도록 실행 중인 프로그램을 일시 중지하도록 요구합니다. 즉, 컴퓨터는 프로그램 실행과 관련된 모든 정보를 기억해야 합니다. 이러한 중단은 치명적이지는 않더라도 일시적입니다. 이러한 중단은 프로그램 코드나 일부 하드웨어 기능(예: 키보드의 키를 누르는 것, 타이머(예: 컴퓨터를 자동으로 끄는 타이머))로 인해 발생할 수 있습니다. 인터럽트 수는 특정 프로세서 생산에 내장된 특정 수로 제한됩니다. 즉, 이를 위해 특수 통신 "채널"이 할당되어 다른 모든 프로세스를 우회하여 프로세서에 액세스할 수 있습니다. 실행 중인 프로그램 코드에 오류가 발생하는 경우(예: 0으로 나누기가 발생하는 경우)에도 인터럽트가 자동으로 생성됩니다. 이러한 중단을 전통적으로 트랩 또는 예외 라고 합니다 . 이러한 경우에는 "예외가 발생했습니다"라고 말하는 것이 일반적입니다. 즉, 예외가 트리거 되었거나 예외가 발생했습니다(발생). 즉 인터럽트 에 대한 요청입니다.“무엇을 해야 합니까?”라는 질문으로 프로세서로 전송됩니다. 이 순간 프로세서는 작동을 멈추고 중지된 지점을 기억하거나 정보가 실행되어야 하는 다음 셀의 클러스터를 기억합니다. 실행된 명령과 실행되지 않은 명령의 전체 체인이 기억됩니다. 그런 다음 프로세서는 이러한 오류가 발생할 경우 조치를 취하기 위해 메모리에서 명령을 읽습니다. 이 명령에 따라 특정 클러스터에 새 값을 입력하거나, 이전에 발생한 오류에 따라 일부 작업 체인 또는 새 주기(예: 반환 또는 루핑 주기)를 추가할 수 있습니다. 다운 명령이 실행됩니다. 컴퓨터 시스템 자체에는 일정 시간이 지나면 실행되는 자동 인터럽트가 많이 내장되어 있습니다. 예를 들어 컴퓨터에서 실행 중인 프로세스를 제어하거나 설정된 알람을 실행하고, 들어오는 외부 신호를 수집하고, 다양한 데이터 변환기를 실행합니다. 여러 가지 이유로 인해 많은 수의 인터럽트가 시스템을 완전히 "정지"시킬 수 있다는 점을 기억할 가치가 있습니다. 프로그램 코드에 오류가 있으면 프로세서가 자동으로 중단되어 정해진 지침에 따라 처리를 시도하게 됩니다. 그러나 모든 인터럽트가 이를 처리하도록 설계된 것은 아닙니다. 또는 우리에게 적합하지 않은 절차를 생성할 수 있습니다. 예를 들어 단순히 애플리케이션이 충돌할 수 있습니다. 따라서 프로그래밍에서는 프로그래머가 잠재적으로 오류 가능성을 확인하는 특정 코드 섹션에 대해 고유한 인터럽트를 구성하는 것이 가능합니다. 이 경우 오류는 프로그램 내에서 처리되며 처리 지침을 위해 프로세서에 접속하지 않습니다. 이러한 블록의 정의는 "예외" 개체를 생성하여 구성됩니다 . 이 객체는 블록에 자동으로 생성됩니다 try-catch. 블록에 >try오류가 있는지 확인하고, 오류가 있으면 프로그램이 블록으로 이동하여 catch오류를 방지하거나 평준화하기 위한 조치를 취합니다. 예를 들어, 키보드에서 숫자를 입력 하고 나중에 더하고 빼야 하는 경우 키보드에서 문자를 입력하면 숫자 로 더할 수 없게 됩니다 (이 두 변수의 합을 문자 S로 표시하겠습니다). 그러므로 우리는 팀으로서 try숫자를 포함하는 숫자 A를 문자를 포함하는 숫자 B(즉, S = A + B)에 추가할 수 있는지 확인해야 하며, 이것이 불가능하고 불가능하다면 확실한 오류가 발생하지 않고 "무엇을 해야 합니까?"라는 질문이 포함된 새로운 인터럽트가 프로세서로 전달되지 않도록 조치를 취해야 합니다. 프로그램에 예외가 없으면 프로세서에 의해 실행이 중단됩니다. 예외가 있는 경우 명령에 의해 "잡히면" 제어가 try명령으로 전달되어 catch대체 솔루션을 설정할 수 있습니다. 예를 들어 이 두 숫자를 추가하지 않고 S = A로 설정합니다.
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 } catch (Exception igogo1) {
   S = a;
 }
 return S;
/* 문자열 "int r = 1;" 오류가 발생하고 프로그램이 작업을 예외 처리기(catch block*/)로 직접 리디렉션하기 때문에 실행되지 않습니다. 따라서 예외가 있다는 것은 프로세서 수준에서 문제를 발생시키지 않고 프로그램 내에서 문제를 해결할 수 있는 기회입니다. try오류가 감지되면 블록에 자동으로 생성되는 “Exception” 개체에는 오류 유형의 값이 포함됩니다. 특정 오류에 대한 설명과 함께 특정 사례에 대해 "OurException"이라고 부르겠습니다. Java 언어 작성자는 일반적인 오류 목록과 이를 수정하기 위한 일반적인 옵션을 미리 만들었습니다. 즉, Java에는 발생한 오류를 처리하기 위해 사용할 수 있는 특정 Exceptions 라이브러리가 있습니다. 처리 코드를 직접 작성하지 않기 때문에 OurException은 이미 누군가가 설명했을 가능성이 높으므로 오류가 잠재적으로 발생할 수 있는 코드를 처리하기 위해 프로그램에 삽입할 예외의 이름만 알면 됩니다. 실수를 해서 라이브러리에서 잘못된 예외를 선택 하면 처리기가 이를 "잡지" 못하고 오류가 프로그램 내에서 해결책을 찾지 못하고 요청이 프로세서로 전송됩니다. 그러나 게으른 자에게도 길은 있다. 라이브러리에서 필요한 예외의 이름을 모르는 경우 위에 설명된 예와 같이 " Exception "이라는 이름의 일반 예외를 사용할 수 있습니다. 예외는 모든 유형의 오류를 처리할 수 있지만 기록할 수 있는 사건에 대한 특정 정보를 제공할 수는 없습니다. 이전에 작성된 예외 라이브러리는 확인된 예외와 확인되지 않은 예외 로 구성됩니다 . 확인 가능한 것은 프로그램 작업을 중단하지 않고 수정할 수 있는 것입니다. 즉, 파일이 존재하지 않는 폴더에서 파일을 열려고 하면 시스템이 이에 대해 알려 주고 파일을 삭제할 수 있습니다. 원하는 폴더에 넣고 프로그램을 계속 진행하세요. 즉, 실제로 인터럽트 요청이 프로세서로 전송되었지만 "이 문제에 대해 무엇을 해야할지 찾아보세요?!?!"라는 질문은 없습니다. 우리는 프로세서가 처리하고 프로그램을 계속 실행하는 기성 명령과 함께 우리가 감지한 인터럽트를 보냈습니다. 선택 취소된 오류는 수정할 수 없으며 프로그램이 완료되기 전에 닫힙니다. 즉, 인터럽트 요청이 프로세서로 전송됩니다., 어떤 경우에도 프로그램 실행이 중단됩니다. 프로그램에서 이러한 예외를 작성할 때 유일한 요점은 사용자가 무슨 일이 일어났는지 이해하도록 하는 것입니다. 왜냐하면 이 중단을 포착하면 정보 메시지를 화면에 표시할 수 있고 이것이 프로그램이 충돌한 이유이기 때문입니다. 이러한 중단을 포착하는 두 번째 이유는 후속 분석을 위해 로그에 이를 기록할 수 있는 기능입니다(해킹을 당했지만 적어도 해킹당한 위치는 알고 있습니다). 그러한 라이브러리가 존재하기 때문에 이를 포함하는 것을 기억해야 합니다. (라이브러리에 대한 확인된 예외 목록과 확인되지 않은 예외 목록은 예를 들어 여기에서 찾을 수 있습니다. ) 포함할 라이브러리를 정확히 알지 못하거나 여러 오류 옵션이 있는 경우 catch필요한 예외를 여러 목록에 나열할 수 있습니다. 시스템 자체는 목록에 있는 경우 올바른 핸들러를 선택합니다. 특정 Exception 대신 이전 블록에서 처리되지 않은 모든 유형 의 Exception을 처리할 수 있는 일반적인 “ Exception ”을 작성할 수 있습니다.
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 }
catch(NullPointerException blabla2) {
   System.out.println("Exception handling code for the NullPointerException.");
 }
catch (ArithmeticException ex1) {
   S = a;
 }
catch(Exception uups1) {
   System.out.println("Exception occured");
 }
 return S;
블록이 있으면 try자동으로 Exception이 생성됩니다. 특정 시점에 예외를 강제로 발생시켜야 하는 경우 해당 명령이 사용됩니다 throw. 즉, 우리는 독립적으로 개체를 생성합니다 new throw. 그 후 프로그램은 작업을 중지하고 프로세서에 인터럽트 요청을 보낸 다음 프로그램 섹션으로 전송되어 catch추가 작업에 대한 지침을 얻으려고 합니다. Exception 을 수동으로 생성하면 라이브러리에서 특정 유형을 지정할 수 있습니다.

throw new ArithmeticException("Access denied - You must be at least 18 years old.");
catch그런 다음 핸들러는 이 특정 예외가 있는 블록을 검색합니다 . 프로그램 전체에서 모든 측면을 검색합니다 catch. 예외 처리 명령 후에는 throw블록에 있는 코드를 제외하고 나머지 모든 프로그램 코드가 실행되지 않습니다 catch. 프로그램에서 핸들러를 찾을 수 없으면 프로세서에 "무엇을 할지 스스로 결정하십시오"라는 질문이 표시되고 프로그램이 중단됩니다. 호출은 ... 블록 new throw내부와 외부 모두에서 가능합니다 (프로그램 내 어디에서나).>try
try {
   /* функция or действие, в котором есть сомнения. То есть: «попробуй выполнить это, а если не получится, а, если не получится, запускай режим исключения» */
   throw new CallForException(); /* Назначаем исключение, которое будет работать в случае наличия ошибки в функции, описанной выше. Здесь исключение «CallForException» - берется из библиотеки существующих исключений */
} catch (CallForException ee1) {
   /* Корректируем ошибку, чтобы программа не «отвалилась» or выводим сообщение об ошибке or что-то ещё */
} finally {
   /* этот блок работает всегда независимо от того была ошибка or нет. А если была, то сработало ли решение в catch or нет */
   /* часто используется для подчистки хвостов, например, для закрытия запущенного file or базы данных */
   /* в ряде случаев блок catch вообще может быть опущен и оставлен только блок finally и наоборот finally может быть опущен и оставлен только catch */
   /* Не допускается использование этого блока в ряде случаев, например, когда функция System.exit() запущена or другие системные Исключения, типа «отключение электроэнергии» и т.п. */
}

예외 통지

이전에 누군가가 작성한 메소드에는 예외 발생이 포함될 수 있습니다. 안전을 위해 코드를 작성한 프로그래머는 후속 프로그래머에게 자신이 작성한 메서드에서 오류가 발생할 수 있다고 경고했습니다. 예를 들어, 아래에 설명된 파일 생성 방법은 파일을 생성할 때 오류가 발생할 수 있다고 규정합니다(주어진 경로에 파일이 없음). 이는 오류 처리기가 필요함을 의미합니다.
public void createFile(String path, String text) throws IOException {
    FileWriter writer = new FileWriter(path, true);
    writer.write(text);
    writer.close();
}
그러나 동시에 핸들러 자체가 없으므로 이제 일반 모드에서는 프로그램에서 작성된 메소드를 간단히 호출할 수 없습니다. 이제 오류 핸들러를 작성하고 블록에서 이 메소드를 호출해야 합니다 try.
String filePath = "hello.txt";
String text = "Hello World";

try {
    createFile(filePath, text);
} catch (IOException ex) {
    System.err.println("Error creating file: " + ex);
}

기본 예외

기존 라이브러리가 충분하지 않은 경우 특정 오류를 처리하기 위해 고유한 예외를 작성하는 것이 가능합니다. 이를 위해 Exception 클래스를 상속하는 클래스를 생성하면 됩니다.
public class StudentNotFoundException extends Exception {

    public StudentNotFoundException (String message) {
        super(message);
    }
}
자신만의 예외를 생성할 때 명심해야 할 두 가지 규칙이 있습니다.
  1. 클래스 이름은 "Exception"으로 끝나야 합니다.
  2. 클래스에는 예외 문제의 세부 사항을 설명하는 문자열 변수가 있는 생성자가 포함되어야 합니다. 생성자에서 슈퍼 생성자가 호출되고 메시지가 전달됩니다.
생성된 예외를 사용하는 예:
public class StudentManager {
    public Student find(String studentID) throws StudentNotFoundException {
        if (studentID.equals("123456")) {
            return new Student();
        } else {
            throw new StudentNotFoundException(
                "Could not find student with ID " + studentID);
        }
    }
}
다음 코드를 사용하여 이 예외를 포착합니다.
public class StudentTest {
    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
         try {
            Student student = manager.find("0000001");
        } catch (StudentNotFoundException ex) {
            System.err.print(ex);
        }
    }
}
프로그램 실행 결과는 다음과 같습니다. StudentNotFoundException: ID가 0000001인 학생을 찾을 수 없습니다.

왜 예외를 작성해야 합니까?

1996년에는 부동 소수점 변수를 정수 변수로 잘못 변환하여 아리안 5 호 로켓이 추락했습니다. 이 상황에는 예외나 처리자가 없었습니다. 파일을 다운로드하는 동안 인터넷 연결이 끊긴 경우 예외가 있으면 연결이 복원된 후에도 다운로드를 계속할 수 있습니다. 예외가 없으면 다운로드를 다시 시작해야 합니다.

참고자료:

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION