Java Standard - 예외처리(Exception Handling)
예외처리
Java Standard - 예외처리(Exception Handling)
프로그램 오류
- 프로그램 에러, 오류: 프로그램이 실행 중 오작동을 하거나 비정상적으로 종료되는 것의 원인
- 종류
- 발생 시점에 따라
- 컴파일 에러: 컴파일 시 발생하는 에러
- 런타임 에러: 실행 시에 발생하는 에러
- 이 외
- 논리적 에러: 실행은 되지만, 의도와는 다르게 동작하는 것
- 발생 시점에 따라
- 에러와 예외
- 프로그램 코드로 대비가 될 수 있느냐 없느냐의 차이
- 에러: 프로그램 코드에 의해 수습될 수 없는 심각한 오류
- 예외: 프로그램 코드에 의해 수습될 수 있는 다소 미약한 오류
예외 클래스의 계층구조
Exception과 Error
예외클래스의 계층구조
- 자바에서는 예외(=Exception Class)와 오류(=Error Class)도 class로 정의
- 이 두개의 클래스도 모든 class의 최고 조상 Object Class를 상속 받음
Exception Class
Exception Class와 RuntimeException Class의 상속계층도
Exception의 구분
- Excpetion과 이 클래스의 자손: 외적인 요인에 의해 발생하는 예외
- Runtime Exception과 이 클래스의 자손: 프로그래머의 실수로 발생하는 예외
예외처리하기 try - catch 문
- 정의: 프로그램 실행 시 발생할 수 있는 예외에 대비한 코드를 작성하는 것
- 목적: 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것
예외를 처리하지 못하면? 프로그램은 비정상적으로 종료되며, 처리되지 못한 예외는 JVM의
예외처리기
가 받아 예외의 원인을 화면에 출력한다.
1
2
3
4
5
try{
//예외가 발생할 가능성이 있는 코드들 작성
}catch(Exception1 e){
//Exception1 발생한 경우, 이를 처리하기 위한 문장을 작성
}
- try 블럭 다음에는 여러 종류의 예외를 처리할 수 있는 하나 이상의 catch블럭을 작성
- catch블럭을 여러개 작성해도 이 중에서 단 한개의 catch블럭만이 수행됨
- 발생한 종류와 일치하는 catch 블럭이 없으면 예외는 처리되지 않음
try - catch문에서의 흐름
try블럭 내에서 예외가 발생한 경우
- 발생한 예외와 일치하는 catch블럭이 있는지 확인한다.
- 일치하는 catch블럭을 찾으면,
- 그 catch블럭 내에 문장을 수행한다.
try-catch
블럭을 빠져나가 다음 문장을수행한다.
이때, try 블럭에서 예외가 발생한 이후 부분은 실행되지 않음으로 try 블럭에 포함 시킬범위를 잘 선택해야한다.
- 일치하는 catch블럭을 찾지 못하면,
- 그 예외는 처리되지 못한다.
try블럭 외에서 예외가 발생한 경우
- catch블럭을 거치지 않고,
try-catch
블럭을 빠져나가 다음 문장을수행한다.
예외의 발생과 catch블럭
catch문의 구조
- 괄호(): 처리하고자 하는 예외의 참조변수를 선언
- 블럭{}: 예외를 처리하고자 하는 로직
예외 발생시, 동작
- 발생한 예외에 해당하는 클래스 인스턴스가 생성
- catch블럭의 괄호 내에 선언된 참조변수와 생성된 인스턴스를
instanceof
연산자로 검사 - 검사결과가
true
가 나올때까지 위에서부터 아래로 진행 - 끝까지 안나오면 예외는 처리되지 않고, 나오면 해당 catch블럭을 수행한뒤 빠저나감
Exception
클래스로 예외처리를 하면 한번에 모든 예외들이 처리가 되는 이유instanceof
연산자를 사용해서 비교를 하기 때문에, 모든 예외의 부모 클래스인 Exception 클래스로 하면 모든 예외가 처리가 되는 것! 또 catch블럭의 검사를 위에서부터 아래로 순차적으로 하기 때문에 넓은 범위의 예외 클래스( 부모 클래스)를 아래에 위치해 놓으면 필요로하는 자식 클래스 외에는 예외 처리를 동일하게 할 수 있음
getPrintStackTrace()
와 getMessage()
getPrintStackTrace()
: 예외 발생 당시의 호출스택의 메서드의 정보와 예외 메세지를 출력getMessage()
: 발생한 예외 클래스의 인스턴스에 저장된 메시지를 얻을 수 있음
멀티 블럭
- catch블럭의 ()내에
|
를 이용해 두개 이상의 예외 클래스를 합칠 수 있다. - 연결된 클래스가 상속 관계에 있으면 컴파일 에러 → 부모 클래스만 적어도 되기 때문
- 이때의 참조변수는 상수, 연결된 클래스의 공통타입 → 형변환 해서 사용
예외 발생시키기
1
2
3
4
5
//1. 예외 클래스 생성, 이때 생성자에 넣은 String은 getMessage로 꺼낼 수 있음
Exception e = new Exception("인스턴스 메세지 작성 내용");
//2. 키워드 throw를 이용해 예외를 발생
throw e;
RuntimeException 과 Exception
- RunctimeException: unchecked 예외 → 컴파일러가 예외처리를 확인하지 않음
- Exception : checked 예외 → 컴파일러가 예외처리를 확인, 예외처리를 하지 않으면 컴파일 오류 발생
메서드에 예외 선언하기
- 방법: 키워드
throws
를 사용해 메서드를 사용할 때 발생할 수 있는 예외를 적어주기만 하면됨 - 의미
- 메서드를 사용하는 쪽에서 이 예외에 대한 처리를 강요하는 것
- 해당 메서드 오버라이딩 시에는 상속관계까지 고려를 해야함
- 예외를 처리하는 것이 아니라 메서드를 호출한 메서드에게 예외를 전달해 예외처리를 떠맡기는 것
- 예외는 계속해서
throws
로 떠맡겨질 수 있지만, 어느 한 곳에서도 예외처리를 해주지 않는다면, 해당 예외가 처리되지 않아 비정상 종료됨 - 예외처리를 받은 메서드는, 전달해준 메서드에서 예외가 발생한 것으로 간주하고 이에대한 처리를 진행
- 예외는 계속해서
예외를 선언하는 기준: 반드시 처리해주어야하는 예외들만 선언
→ check Exception, 이건 처리하지 않으면 컴파일 오류 발생하기 때문
finally 블럭
- 의미: 예외의 발생여부에 관계없이 실행되어야할 코드, 선택적으로 텃붙여 사용
1
2
3
4
5
6
7
8
try{
//예외가 발생할 가능성이 있는 코드들 작성
}catch(Exception1 e){
//Exception1 발생한 경우, 이를 처리하기 위한 문장을 작성
}finally{
//예외의 발생 여부와 관계없이 항상 수행되어야하는 문장을 작성
//try-catch블럭 맨 마지막에 위치
}
- 순서
- 예외 발생시 : try → catch → finally
- 예외 미발생시 : try → finally
- 특징
- try블럭이나 catch블럭에서 return문이 있어도 finally문을 실행 한 뒤에 메서드를 종료
자동 자원 반환 try - with - resources문
- 정의: try-catch문의 변형으로, try블럭의 괄호 안에 선언된 객체가 try블럭을 벗어나면 자동으로
close()
가 호출되고, 이 외에는 try-catch문과 같음- 자동으로
close()
가 호출될 수 있으려면,AutoCloseable
인터페이스가 구현되어 있어함
- 자동으로
1
2
3
4
5
try(//객체를 생성하는 문장을 작성, 여러줄이면 ; 으로 구분){
//이를 이용한 코드 작성
}catch(Exception1 e){
//Exception1 발생한 경우, 이를 처리하기 위한 문장을 작성
}
사용자 정의 예외 만들기
- 방법: Exception(checked)와 RunctimeException(unchecked) 중에 하나를 골라 상속받아 정의
- 메시지를 저장할 수 있으려면 그에 맞는 생성자를 추가해야함
- 그 외에 새로운 멤버변수를 추가해 새롭게 추가할 수도 있음
- 사용자 예외를 정의할 때 예전에는 checked로 했지만, 현재는 unchecked로 많이 하는 편
예외 되던지기(exception re-throwing)
- 정의: 예외를 처리한 후 다시 인위적으로 발생시키는 방법
- 예외를
try-catch문
을 이용해 처리 - catch문에서 필요한 작업을 한 뒤에
throw
를 이용해 예외를 다시 발생 → 메서드 선언부에 지정 해줘야함
- 예외를
- 목적: 히나의 예외에 대해 양쪽 모두에서 처리해줘야 할 작업이 있을때 사용
연결된 예외(chained exception)
- 원인예외: 예외1이 예외2를 발생시켰다면, 예외1이 예외2의
원인예외
- 목적
- 여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위해
- 상속관계로 표현을 해서 부모클래스로 catch블럭을 잡으면, 잘 잡히지만 여러 자식 중 어떤 것 때문에 잡힌 것인지 알 수가 없음
- checked 예외를 unchecd 예외로 변경할 수 있게 하기 위해서
- 여러가지 예외를 하나의 큰 분류의 예외로 묶어서 다루기 위해
This post is licensed under CC BY 4.0 by the author.