에러와 예외
어떤 원인에 의해 오동작 하거나 비 정상적으로 종료되는 경우
삼각도에 따른 분류
- Error
- 메모리 부족, stack overflow 같이 일단 발생하면 복구할 수 없는 상황
- 프로그램의 비 정상적 종료를 막을 수 없음 -> 디버깅 필요
- Exception
- 읽으려는 파일이 없거나 네트워크 연결이 안 되는 등 수습될 수 있는 비교적 상태가 약한 것들
- 프로그램 코드에 의해 수습될 수 있는 상황
exception handling(예외 처리)란
- 예외 발생 시 프로그램의 비 정상 종료를 막고 정상적인 실행 상태를 유지 하는 것
- 예외의 감지 및 예외 발생 시 동작할 코드 작성 필요
예외 클래스의 계층

checked exception
- 예외에 대한 대처 코드가 없으면 컴파일이 진행되지 않음
unchecked exception (RuntimeException의 하위 클래스)
- 예외에 대한 대처 코드가 없더라도 컴파일은 진행됨
try~catch 구문
<java />
try{
// 예외가 발생할 수 있는 코드
} catch(XXException e){
// 예외가 발생했을 때 처리할 코드
}
Throwable의 주요 메서드
public Sring getMessage() - 발생된 예외에 대한 구체적인 메시지를 반환
public Throwable getCause() - 예외의 원인이 되는 Throwable 객체 또는 null을 반환
public void printStackTrace() - 예외가 발생된 메서드가 호출되기까지의 메서드 호출 스택을 출력, 디버깅 수단으로 주로 사용
try-catch문에서의 흐름
- try블록에서 예외가 발생하면 JVM이 해당 Exception 클래스의 객체 생성 후 던짐 = (throw) throw new XXException()
던져진 exception을 처리할 수 있는 catch 블록에서 받은 후 처리 = 적당한 catch 블록을 만나지 못하면 예외처리는 실패
정상적으로 처리되면 try-catch 블록을 벗어나 다음 문장 진행
try 블록에서 어떠한 예외도 발생하지 않은 경우
- catch 문을 거치지 않고 try-catch블록의 다음 흐름 문장을 실행
다중 exception handling
- try 블록에서 여러 종류의 예외가 발생할 경우
- 하나의 try블록에 여러 개의 catch 블록 추가 가능
<java />
try {
//
} catch (xxException e){
//
} catch (yyException e){
//
} catch (zzException e){
//
}
JVM이 던진 예외는 catch문장을 찾을 때는 다형성이 적용됨
상위 타입의 예외가 먼저 선언되는 경우 뒤에 등장하는 catch 블록은 동작할 기회가 없음
상속 관계가 없는 경우는 무관
상속 관계에서는 작은범위에서 큰 범위순으로 정의
다중 예외 처리를 이용한 checked exception 처리
처리하지 않으면 컴파일 불가 : Checked Exception
예외 처리는 가능한 구체적으로 진행
발생하는 예외들을 하나로 처리하기
- 예외 상황 별 처리가 쉽지 않음
- 가급적 예외 상황 별로 처리하는 것을 권장
심각하지 않은 예외를 굳이 세분화 해서 처리하는것도 낭비
계층을 이루는 예외의 처리
Object -> Throwable -> [Error, Exception] Exception -> [IOException, RuntimeException, ...]
try ~ catch ~ finally 구문을 이용한 예외 처리
finally는 예외 발생 여부와 상관 없이 언제나 실행
- 중간에 return을 만나는 경우도 finally 블록을 먼저 수행 후 리턴 실행
<java />
try {
// exception이 발생할 만한 코드 - system자원 사용
} catch (Exception e) {
// exception 발생 시 처리 코드
} finally {
// try block에서 접근했던 system자원의 안전한 원상 복구
}
try-with-resources
JDK 1.7이상에서 리소스의 자동 close 처리
try선언문에 선언된 객체들에 대해 자동 close 호출(finally 역할)
- 단 해당 객체들이 AutoCloseable interface를 구현할 것
- 해당 객체는 try블록에서 다시 할당도리 수 없음
*try블럭은 느리므로 최소화하자
throws 키워드를 통한 처리 위임
method에서 처리해야 할 하나 이상의 예외를 호출한 곳으로 전달(처리 위임)
- 예외가 없어지는 것이 아니라 단순히 전달됨
- 예외를 전달받은 메서드는 다시 예외 처리의 책임 발생
<java />
void exceptionMethod() throws Exception1, Exception2... {
}
void methodCaller() {
try {
exceptionMethod();
} catch(Exception e) {}
}
처리하려는 예외의 조상 타입으로 throws 처리 가능
checked exception과 throws
checked exception은 반드시 try~catch 또는 throws 필요
필요한곳에서 try~catch 처리
runtime exception과 throws
runtime exception은 throws 하지 않아도 전달되지만
결국 try~catch로 처리해야함
로그분석과 예외의 추적
Throwable의 printStackTrace는 메서드 호출 스택 정보 조회 가능
- 최초 호출 메서드에서부터 예외 발생 메서드 까지의 스택 정보 출력
메서드 재정의와 throws
메서드 재정의 시 조상 클래스 메서드가 던지는 예외보다 부모예외를 던질 수 없다
<java />
String s = "1000" int num = Integer.parseInt(s, 2); // 2진수
catch (aException | bException){} 가능
사용자 정의 예외
API에 정의된 exception이외에 필요에 따라 사용자 정의 예외 클래스 작성
대부분 Exception 또는 RuntimeException 클래스를 상속받아 작성
- checked exception 활용 : 명시적 예외 처리 또는 throws 필요
- 코드는 복잡해지지만 처리 누락 등 오류 발생 가능성은 줄어듦
- runtime exception 활용 : 묵시적 예외 처리 가능
- 코드가 간결해지지만 예외 처리 누락 가능성 발생
사용자 정의 예외를 만들어 처리하는 장점
- 객체의 활용 - 필요한 추가정보, 기능
- 활용 가능 코드의 재사용 - 동일한 상황에서 예외 객체 재사용 가능
- throws 메커니즘의 이용 - 중간 호출 단계에서 return 불필요
*강제화시키고 싶으면 Exception 반강제화시키고 싶으면 Runtime Exception
<java />
class FruitNotFoundException extends Exception {
public FruitNotFoundException(String name) {
super(name + "에 해당하는 과일은 없습니다.");
}
}
...
getFruit2(String name) throws FruitNotFoundException {
...
sthrow new FruitNotFoundException(name); // 오류 발생시키기
...
}
'Java' 카테고리의 다른 글
[Java] I/O와 Stream (0) | 2023.02.01 |
---|---|
[Java] List, Set, Map, Sort (0) | 2023.02.01 |
[Java] 추상클래스, 인터페이스, Generic (0) | 2023.01.31 |
[Java] 다형성, 정적 바인딩, 동적 바인딩 (0) | 2023.01.31 |
[Java] Singleton 디자인 패턴 (0) | 2023.01.31 |