공부일기/JAVA

JAVA 공부일기1-9

고다나 2023. 4. 25. 17:28

 

Java의 정석 기초편
Chapter 8 예외처리

 

1. 프로그램 오류

프로그램 실행 중 어떤 원인에 의해서 오작동하거나 비정상적으로 종료되는 경우를 발생시키는 원인. 

컴파일 에러: 컴파일 할 때 발생하는 에러.

런타임 에러: 실행 시에 발생하는 에러.

논리적 에러: 실행은 되지만, 의도와는 다르게 동작하는 것.

 

에러는 프로그램 코드에 의해 수습x, 예외는 프로그램 코드에 의해 수습o.

 

2. 예외 클래스의 계층구조

자바의 정석 기초편1 p.293
자바의 정석 기초편1 p.293

Exception클래스들: 사용자의 실수와 같은 외적 요인에 의해 발생.

RuntimeException클래스들: 프로그래머의 실수로 발생.

 

3. 예외처리하기- try-catch문

정의: 프로그램 실행 시 발생할 수 있는 예외 발생에 대비한 코드 작성

목적: 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것.

 

try{

       //예외 발생할 가능성 있는 문장들

} catch (Exception e1) {  // () 내에는 처리하고자 하는 예외와 같은 타입의 참조변수 선언.

        // Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적음.

} catch (Exception e2) {...}

 

▶ try 블럭 내에서 예외가 발생한 경우,

1. 발생한 예외와 일치하는 catch 블럭 있는지 확인. 예외가 발생하면, 발생한 예외에 해당하는 클래스의 인스턴스가 생성.

2-1. 첫 번째 catch 블럭부터 차례로 내려가면서 catch 블럭의 ()내에 선언된 참조변수의 종류와 생성된 예외클래스의 인스턴스에 instanceof 연산자를 이용해서 검사. 일치하는 catch 블럭을 찾으면, try 문을 벗어나 일치하는 catch 블럭 내의 문장들을 수행 후 전체 try-catch문을 빠져나가서 그 다음 문장 계속해서 수행.

2-2. 일치하는 catch 블럭을 못 찾으면, 예외 처리x. (모든 예외 클래스는 Exception클래스의 자손이므로, catch블럭의 ()에 Exception 타입의 참조변수를 선언해놓으면 어떤 종류의 예외가 발생하더라도 처리.)

 

▶ try 블럭 내에서 예외가 발생하지 않은 경우,

catch 블럭을 거치지 않고 전체 try-catch문을 빠져나가서 그다음 문장 계속해서 수행.

 

printStackTrace(): 예외발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지 화면에 출력.

getMessage(): 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있음.

 

멀티 catch블럭

jdk1.7부터 '|'기호를 사용해 하나의 catch 블럭으로 합칠 수 있음. ex) catch(ExceptionA | ExceptionB e){...}

두 예외 클래스가 조상-자손 관계라면 컴파일 에러 → 조상 클래스만 써주는 것과 동일하기 때문에 중복 제거를 위함.

멀티catch블럭 내에서는 실제로 어떤 예외가 발생한 것인지 알 수 없음.  그래서 참조변수 e로 멀티 catch 블록에 연결된 예외클래스들의 공통분모인 조상예외 클래스에 선언된 멤버만 사용할 수 있음.

 

4. 예외 발생시키기

키워드 throw를 사용해 츠로그래머가 고의로 예외를 발생시킬 수 있음.

연산자 new를 이용해 발생시키려는 예외 클래스의 객체를 만든 다음,  Exception e = new Exception("고의로 발생시킴");

키워드 throw를 이용해서 예외를 발생시킴. throw e;

 

5. checked예외, unchecked예외

Exception클래스와 그 자손들(checked예외)이 발생 가능성이 있는 문장들에 예외처리를 하지 않으면 컴파일이 되지 않음.

RuntimeException클래스와 그 자손들(unchecked예외)에 해당하는 예외는 프로그래머가 실수로 발생하는 것들이기 때문에 예외처리를 강제하지 않음.

 

6. 메서드에 예외 선언하기

메서드의 선언부에 키워드 throws를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어줌. 예외가 여러 개일 경우 쉼표로 구분. void method() throws Exception1, Exception2,,,{...}

 

예외가 처리된 것은 아니고 예외를 단순히 전달한 것. 결국 어느 한 곳에서 반드시 try-catch문으로 예외처리를 해줘야 함. (예외가 발생한 메서드 내에서 자체적으로 처리해도 되는 경우 메서드 내에 try-catch문을 넣어 처리하고, 메서드 내에서 자체적으로 해결이 안 되는 경우 예외를 선언해서 호출한 메서드가 처리하도록 함.)

 

7. finally블럭

finally블럭은 예외의 발생여부에 상관없이 실행되어야 할 코드를 포함시킬 목적. try-catch문 끝에 덧붙여 사용 가능.

 

8. 예외 되던지기

예외를 처리한 후 인위적으로 다시 발생시킴. 예외가 발생할 가능성이 있는 메서드에서 try-catch문을 사용해서 예외를 처리해주고 catch문에서 필요한 작업을 행한 후에 throw문을 사용해서 예외를 다시 발생시킴. 다시 발생한 예외는 이 메서드를 호출한 메서드에 전달되고 호출한 메서드의 try-catch문에서 예외를 또다시 처리.  하나의 예외에 대해서 예외가 발생한 메서드와 이를 호출한 메서드 양쪽 모두에서 처리해줘야 할 작업이 있을 때 사용.

 

9. 연결된 예외

한 예외가 다른 예외를 발생시킬 수 있음→ 원인예외.

 

Throwable initCause(Throwable cause) 지정한 예외를 원인 예외로 등록

Throwable getCause() 원인 예외를 반환

 

이유1. 여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위함.

이유2. checked예외를 unchecked 예외로 바꿀 수 있도록 하기 위함.