6. 예외 처리
에러와 예외의 구분
에러(Error)
하드웨어의 고장, 오동작은 에러(Error)라고 한다.
자바 코드와 상관없이 JVM이 실행 불능이 된다.
예외(Exception)
사용자의 잘못된 조작, 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다.
에러와 예외의 공통점
처리되지 않은 예외나 에러가 터지면 프로그램이 곧바로 종료된다.
에러와 예외의 차이점
예외는 예외 처리(Exception Handling)를 통해 프로그램이 종료되지 않고 정상 실행상태를 유지하게 만들 수 있다.
예외의 종류
일반 예외 (Exception)
자바소스 컴파일 과정에서 예외를 처리하는지 검사하고 컴파일 오류를 발생시키는 예외이다.
실행 예외 (RuntimeException)
컴파일 과정에서는 예외처리 코드를 검사하지 않는 예외이다.
프로그램 실행 도중 실행 예외가 발생하면, 해당 예외 클래스로 객체를 생성한다.
일반 예외와 실행 예외의 공통점
예외 처리가 필요하다.
java.lang.Exception
클래스를 상속받는다.
일반 예외와 실행 예외의 차이점
일반 예외는
Exception
을 상속받는다.실행 예외는
Exception
과RuntimeException
을 둘 다 상속받는다.
실행 예외의 처리
자바 컴파일러의 체크 대상이 아니기 때문에, 개발자가 직접 경험에 의해 예외처리 코드를 작성해야 한다.
처리하지 않으면, 예외 발생 시 프로그램이 종료된다.
NullPointerException
null
값을 갖는 참조 변수에 객체 접근 연산자인.
(도트)를 사용하면 발생한다.참조할 메모리 주소가 없는데 객체를 사용하려 해서 예외가 발생한다.
ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과하여 사용할 경우 발생한다.
NumberFormatException
잘못된 문자를 숫자로 파싱하려 할 때 발생한다.
ClassCastException
상속했던 부모 클래스로 타입을 캐스팅 하는 것 혹은 상속했던 인터페이스로 타입을 변경하는 것과 같은 정상적인 캐스팅이 아닌 비정상적인 캐스팅을 하면 발생한다.
ClassCastException
을 발생시키지 않기 위해서는 해당 클래스가X
의 인스턴스인지 확인하는instanceof X
와 같은 연산자로 확인하는 것이 좋다.
예외 처리 코드
프로그램에서 예외가 발생했을 때, 프로그램의 갑작스러운 종료를 막고 정상실행을 유지하도록 처리하는 코드를 예외처리 코드라고 한다.
일반 예외가 발생하는 코드를 작성하면 자바 컴파일러는 예외 처리 코드 작성을 강제한다.
예외처리 코드는
try-catch-finally
를 이용한다.finally
는 예외처리와 상관없이 무조건 실행되는 코드 블럭이다.try
혹은catch
에서return
문을 사용하더라도 항상 실행된다.
예외 종류에 따른 처리 코드
다중 catch
catch
블록은 단 하나만 쓸 수 있는 게 아니라, 상황에 따라 여러개를 겹쳐 쓸 수 있다.catch
블록이 여러 개인 경우 여러 개의catch
블록 중 하나만 실행된다.catch
의 예외는 더 적은 예외를 포괄하는 하위 클래스일수록 더 위로 와야 한다.이를테면
Exception
은 모든 예외를 포함하기 때문에,Exception
이 가장 위에 있는 경우 어떠한 다른 예외catch
블록으로도 넘어갈 수 없게 된다.
멀티 catch
자바7부터 하나의
catch
블록에서 여러 개의 예외처리가 가능한 멀티catch
기능을 추가했다.
자동 리소스 닫기
자바7부터
try-with-resources
를 사용하면 예외 발생 여부와 상관없이 사용했던 리소스 객체의.close()
메소드를 호출해서 안전하게 리소스를 닫아준다.리소스 객체의 종류로는 입출력 스트림, 서버 소켓, 소켓, 각종 채널 등이 있다.
단일 리소스인 경우
복수 리소스인 경우
자동 리소스 닫기가 가능한 조건
리소스 클래스에서
AutoClosable
이라는 인터페이스를 상속해야 한다.
위와 같이 ExampleResource
클래스와 Main
클래스를 구현하면,
실행 결과로 위와 같은 결과가 나온다.
AutoClosable
인터페이스에서 오버라이드하여 구현한 .close()
메소드가 자동으로 호출되는 것을 볼 수 있다.
예외 떠넘기기
throws
키워드를 이용해 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘길 수 있다.
위와 같이 throws
를 통해 예외를 떠넘기는 메소드를 호출할 때는 해당 예외를 try ... catch
문으로 처리하거나 또 한번 throws
를 통해 예외를 떠넘기거나 해야 한다.
위의 코드에서 컴파일러가 행동을 강제한다.
자바 API 도큐먼트에서 예외 표기
자바 API 도큐먼트 사이트에서는 위와 같이 throws
로 해당 메소드가 어떤 예외를 던지는지 잘 표기되어 있다.
main 메소드에서의 throws
main
메소드에서 throws
로 예외를 던져버리면, 사용자 입장에서는 갑자기 알 수 없는 메세지가 뜨며 프로그램이 종료되기 때문에 주의해야 한다.
사용자 정의 예외와 예외 발생
개발자가 만든 애플리케이션 서비스와 관련된 예외 등을 개발자가 직접 만들 수 있다.
사용자 정의 예외 클래스 선언
일반 예외는
Exception
클래스를 상속한다.실행 예외는
RuntimeException
클래스를 상속한다.사용자 정의 예외 클래스명은
Exception
으로 끝내는 것이 관례이다.생성자 2개를 관례적으로 포함한다.
아무런 내용이 없는 생성자
String
타입의 메세지를 받아 전달하기 위한 생성자메세지를 상위 클래스로 넘겨
catch
블록에서 이용할 수 있게 해준다.
코드에서 예외를 고의로 발생시키는 방법
예외에 대한 정보 얻기
catch(Exception e) { ... }
블록에서 넘어온Exception e
변수를 이용한다.e.getMessage()
:Exception
클래스로 넘어온 예외 메세지를 가져올 수 있다.e.printStackTrace()
: 예외 발생 코드를 추적해서 모두 콘솔에 출력한다. 어떤 예외가 어디에서 발생했는지 상세하게 출력해준다.
Last updated