728x90
- 오류(Error): 일반적으로 회복이 불가능한 문제
- 시스템 레벨에서, 또는 주로 환경적인 이유로 발생
- 에러가 발생한 경우 어떠한 에러로 프로그램이 종료되었는지 확인하고 대응
- 예외(Exception): 일반적으로 회복이 가능한 문제
- 코드레벨에서 할 수 있는 문제상황에 대한 대응은 "예외처리"에 속함
- 예외의 종류
- 코드실행 관점에서
- 컴파일: 프로그래밍 언어로 작성한 코드를 컴퓨터가 이해할 수 있는 언어로 변환하는 것(.java -> .class)
- 컴파일 에러: 언어의 규칙을 지키지 않아서 발생. 문법에 맞게 다시 작성
- 런타임 에러: 컴파일은 잘 되었지만 프로그램 실행 도중 발생
- 예외처리 관점에서
- 확인된 예외(Checked Exception): 컴파일 시점에 확인하는 예외. 반드시 예외 처리를 해야함.
- 미확인된 예외(Unchecked Exception): 런타임 시점에 확인되는 예외. 예외 처리가 반드시 필요하지 않음.
- 코드실행 관점에서
예외처리의 흐름
- 예외 정의하기: 예외 클래스를 만들어 에러를 정의
class OurBadException extends Exception {
public OurBadException() {
super("위험한 행동을 하면 예외처리를 꼭 해야합니다!");
}
}
- 클래스 내의 메서드가 위험하다고 알리기: throw, throws
- throws: 메서드 이름 뒤에 붙어 이 메서드가 어떤 예외사항을 던질 수 있는지 알려주는 예약어
- throw: 메서드 안에서 실제로 예외 객체를 던질 때 사용하는 예약어
- 실제로 던지는 예외 객체 하나와 같이 사용해야 함
- throw 아래의 구문들은 실행되지 않고 throw문과 함께 메서드가 종료됨
class OurClass {
private final Boolean just = true;
public void thisMethodIsDangerous() throws OurBadException {
if (just) {
throw new OurBadException();
}
}
}
- 위험한 메서드를 사용할 때 예외를 handling: try-catch, finally 문
- 1개의 try문에 여러개의 catch문 사용 가능
- throws로 위험한 메서드임을 알렸으니 이 메서드를 사용할 때 예외처리를 하지 않으면 컴파일 에러 발생
public class StudyException {
public static void main(String[] args) {
OurClass ourClass = new OurClass();
try {
// 1. 위험한 메소드의 실행을 "시도" 해 봅니다.
// "시도" 해보는 코드가 들어가는 블럭입니다.
ourClass.thisMethodIsDangerous();
} catch (OurBadException e) {
// 2. 예외가 발생하면, "잡아서" handling 합니다.
// 예외가 발생하는경우 "handling" 하는 코드가 들어가는 블럭입니다.
// 즉 try 블럭 내의 구문을 실행하다가 예외가 발생하면
// 예외가 발생한 줄에서 바로 코드 실행을 멈추고
// 여기 있는 catch 블럭 내의 코드가 실행됩니다.
System.out.println(e.getMessage());
} finally {
// 3. 예외의 발생 여부와 상관없이, 실행시켜야 하는 코드가 들어갑니다.
// 무조건 실행되는 코드가 들어가는 블럭입니다.
System.out.println("우리는 방금 예외를 handling 했습니다!");
}
}
}
자바의 Throwable Class
Chained Exception, 실제 예외 처리하는 방법
- 연결된 예외(Chained Exception)
- 예외는 다른 예외를 유발
- 원인 예외를 새로운 예외에 등록한 후 다시 새로운 예외를 발생시키는데 이를 예외 연결이라고 함
- 예외를 연결하는 이유:
- 여러 가지 예외를 큰 분류의 예외로 묶어서 다루기 위해서
- checked exception을 unchecked exception으로 포장하는데 사용
- 원인 예외를 다루기 위한 메소드
- initCause(): 지정된 예외를 원인 예외로 등록하는 메소드
- getCause(): 원인 예외를 반환하는 메소드
// 연결된 예외
public class main {
public static void main(String[] args) {
try {
// 예외 생성
NumberFormatException ex = new NumberFormatException("가짜 예외이유");
// 원인 예외 설정(지정한 예외를 원인 예외로 등록)
ex.initCause(new NullPointerException("진짜 예외이유"));
// 예외를 직접 던집니다.
throw ex;
} catch (NumberFormatException ex) {
// 예외 로그 출력
ex.printStackTrace();
// 예외 원인 조회 후 출력
ex.getCause().printStackTrace();
}
// checked exception 을 감싸서 unchecked exception 안에 넣습니다.
throw new RuntimeException(new Exception("이것이 진짜 예외 이유 입니다."));
}
}
// 출력
Caused by: java.lang.NullPointerException: 진짜 예외이유
- 실제로 예외 처리하기
1. 예외 복구: 최소한의 대응만 가능한 경우가 많아 자주 사용되지는 않음
public String getDataFromAnotherServer(String dataPath) {
try {
return anotherServerClient.getData(dataPath).toString();
} catch (GetDataException e) {
return defaultData;
}
}
2. 예외 처리 회피
public void someMethod() throws Exception { ... }
public void someIrresponsibleMethod() throws Exception {
this.someMethod();
}
someMethod()에서 발생한 에러가 someIrresponsibleMethod()의 throw를 통해 흘러나감
3. 예외 전환
public void someMethod() throws IOException { ... }
public void someResponsibleMethod() throws MoreSpecificException {
try {
this.someMethod();
} catch (IOException e) {
throw new MoreSpecificException(e.getMessage());
}
}
someMethod()의 예외가 잡히면 조금더 적절한 예외를 다시 throw
'[스파르타코딩클럽] > Java 문법 종합반' 카테고리의 다른 글
Chapter 12. 스레드 (0) | 2023.10.18 |
---|---|
Chapter 11. 제네릭(Generic) (0) | 2023.10.17 |
Chapter 9. 인터페이스 (0) | 2023.10.17 |
Chapter 8. 상속 (0) | 2023.10.16 |
Chapter 7. 클래스 (0) | 2023.10.16 |