ch14 : 예외
목차
try-catch 구문
참고로 오류 출력할 때는
System.out.println()
이것보다System.err.println()
을 사용하는 것이 좋음! (IDE에서 다른 색으로 표시됨)
try 구문에서 오류 발생시
예외 발생 이후 문장은 처리하지 않고 catch구문으로 이동함
변수 범위!
try 블록 안에서 선언한 변수는 catch블록에서 사용할 수 없다.
보통 catch 문장에서 사용할 변수는 try 앞에 미리 선언하여 사용한다.
finally 블록
try-cath 구문 이후에 예외발생여부와 상관없이 실행되는 블록
코드의 중복을 피하기 위해 반드시 필요하다.
catch 블록
catch 블록은 여러 개를 사용할 수 있다. 단, 이때는 catch 블록들의 순서가 중요하다.
먼저 선언한 catch 블록에서 예외가 잡히면, 다음 블록은 pass한다.
이때, 먼저 선언된 catch 블록이 이후 선언된 catch 블록의 부모 예외 클래스면, 컴파일 에러가 발생한다. (이후 선언된 catch 블록은 의미가 없으므로)
모든 예외의 부모 클래스는 java.lang.Exception 클래스다. 또한, 발생한 예외가 catch 블록에 해당하지 않으면 예외가 발생하면서 스레드가 종료된다.
따라서 Exception을 가장 마지막 catch 블록에 배치하여 안전한 프로그램을 만드는 것이 좋다.
예외의 종류
종류
error
Runtime exception (unchecked exception)
checked exception
Error
자바 프로그램 밖에서 발생한 경우 (디스크 고장 등)→ 개발자가 신경 쓸 필요X
Error는 프로세스에 영향을 주고, Exception은 쓰레드에만 영향을 준다.
ex) OutOfMemoryError, ThreadDeath, StackOverflowError
Runtime exception (런타임 예외), Unchecked exception라고도 함
Runtime 시점에 발생하는 예외로, 프로그램을 실행할 때(컴파일 시) 체크해주지 않아도 되는 예외들
이 경우 따로 에러 처리(try/catch or throw)를 하지 않는다. 예외 처리를 직접 하기보다는 예외가 발생하지 않도록 프로그래머가 주의해야 한다.
컴파일시에 체크하지 않고, 실행시에 발생하는 예외이므로 unchecked exception이라고도 한다.
Runtime Exception을 확장한 예외들이다.
ex) ArrayIndexOutOfBoundsException, NullPointerException
Checked exception
Runtime 시점에 발생하지 않고 Compile 시점에 발생해서 무조건 체크해야하는 예외들
반드시 에러 처리(try/catch or throw)를 해야하는 경우
Exception을 바로 확장한 예외들이다.
ex) FileNotFoundException, ClassNotFoundException
❔Unchecked exception VS Checked exception ?
Checked exception는 정상적인 프로그램에서 일반적으로 발생할 수 있는 예외사항이지만, (ex. 사용자가 파일명을 잘못 입력한 경우) Unchecked exception는 프로그램 설계의 잘못으로 발생하는 버그가 대부분이다. (ex. 개발자의 코드 누락)
일반적으로 사용자가 프로그램 사용중에 만드는 exception들은 Checked exception에 해당한다. 예를 들어, 사용자가 존재하지 않은 파일을 호출할 경우 FileNotFoundException이 발생하고, 이때는 에러 처리(try/catch or throw)를 통해 다시 입력하라는 메세지를 전달해줄 수 있다. 참고 링크
반면, 만약 개발자가 '사용자가 입력한 파일명'을 통해 어떤 메소드에 접근하는 코드를 작성해야하는데, 파일명을 가져오는 코드를 누락해서 null에 접근해서 메소드를 호출할 경우는 Unchecked exception이다. 이는 에러처리가 아니라 에러가 발생하지 않도록 코드 누락이 없게 개발자가 주의해야 한다. 참고 링크2
이론적으로는 위와 같지만, Checked Exception을 Unchecked Exception으로 throw하는 게 좋다.
Throwable
모든 예외(Exception 혹은 Error)는
Throwable
클래스를 상속받는다.따라서 Exception이나 Error를
Throwable
로 처리해도 된다.Throwable()
Throwable()
Throwable(String message)
예외 메세지 전달Throwable(Throwable cause)
예외 원인을 전달
Throwable에 선언된, 그리고 Exception 클래스에서 오버라이딩된 메소드들
getMessage() : 예외 메세지를 String 형태로 받는다. 어떤 예외가 발생했는 지 확인할 떄 사용한다.
ex)
예외.getMessage();
// null 출력
toString(): getMessage보다 더 자세하게, 예외 클래스명도 확인할 수 있다.
ex)
예외.toString();
// java.lang.NullPointerException 출력
printStackTrace() : 첫 줄에 예외 메세지를 출력하고, 두번째부터는 예외가 발생하게 된 메서드들의 호출 관계(스택 트레이스)를 출력한다. (다만 로그가 많이 쌓이므로 개발 시에만 사용할 것)
throws
throw : 예외 발생시키기
try-catch 블록에서 사용하는 방법
이때 throw한 예외 클래스가 catch 블록에 없으면 컴파일 에러가 발생한다.
throws와 같이 사용(메소드 밖으로)
이떄 throw한 예외 클래스가 해당 메소드의 throws 선언 뒤에 없으면 컴파일 에러가 발생한다.
throws : 메소드 밖으로 보내기 (처리 위임)
해당 메소드를 호출한 메소드에게 예외 전달함
이때 호출한 메서드에서는 반드시 해당 예외를 try-catch 블록으로 처리해야 한다.
두가지 이상의 예외를 던질 경우, 콤마로 구분하여 적어줄 것
throws를 선언한 매서드를 호출한 메서드 쪽에선 이 호출한 메서드를 반드시 try-catch블럭으로 감싸야 한다.
예외를 throw하는 이유는 해당 메서드에서 예외를 처리하지 못하는 상황이거나, 미처 처리하지 못한 예외가 있을 경우 대비하기 위함이다.
단, throws한걸 또 throws하는건 좋지 않다. throws 하는 메서드를 호출하는 쪽에서 try-catch로 처리하는 것이 가장 좋다.
예외 만들기
Exception 예외 만들기
Throwable
혹은Throwable
의 자식 클래스(Exception
등)의 상속을 받아야 한다.ex)
자바의 예외 처리 전략
실행 시에 발생할 확률이 높은 경우, 런타임 에러로 만드는 것이 좋을 수 있다 (
extends RuntimeException
) ⇒>>???'java exception strategy' 검색하여 참고할 것
Last updated