이것이 자바다 정리 #6 예외 처리
이것이 자바다 책을 참고하였습니다.
java.lang.Exception
클래스를 상속받는다.Exception
을 상속받는다.Exception
과 RuntimeException
을 둘 다 상속받는다.null
값을 갖는 참조 변수에 객체 접근 연산자인 .
(도트)를 사용하면 발생한다.Integer.parseInt("삼백"); // NumberFormatException 발생
Integer.parseInt("300a"); // NumberFormatException 발생
ClassCastException
을 발생시키지 않기 위해서는 해당 클래스가 X
의 인스턴스인지 확인하는 instanceof X
와 같은 연산자로 확인하는 것이 좋다.try-catch-finally
를 이용한다.finally
는 예외처리와 상관없이 무조건 실행되는 코드 블럭이다.try
혹은 catch
에서 return
문을 사용하더라도 항상 실행된다.catch
블록은 단 하나만 쓸 수 있는 게 아니라, 상황에 따라 여러개를 겹쳐 쓸 수 있다.catch
블록이 여러 개인 경우 여러 개의 catch
블록 중 하나만 실행된다.catch
의 예외는 더 적은 예외를 포괄하는 하위 클래스일수록 더 위로 와야 한다.Exception
은 모든 예외를 포함하기 때문에, Exception
이 가장 위에 있는 경우 어떠한 다른 예외 catch
블록으로도 넘어갈 수 없게 된다.try {
} catch(FirstException e) {
} catch(SecondException e) {
}
catch
블록에서 여러 개의 예외처리가 가능한 멀티 catch
기능을 추가했다.try {
} catch (FirstException | SecondException e) {
}
try-with-resources
를 사용하면 예외 발생 여부와 상관없이 사용했던 리소스 객체의 .close()
메소드를 호출해서 안전하게 리소스를 닫아준다.try (FileInputStream fis = new FileInputStream("file.txt")) {
// ...
} catch (Exception e) {
// ...
}
try (FileInputStream fis = new FileInputStream("file1.txt");
FileOutputStream fos = new FileOutputStream("file2.txt")) {
// ...
} catch (Exception e) {
// ...
}
AutoClosable
이라는 인터페이스를 상속해야 한다.public class ExampleResource implements AutoCloseable{
@Override
public void close() throws Exception {
System.out.println("close method called");
}
}
public class Main {
public static void main(String[] args) {
ExampleResource exampleResource = new ExampleResource();
try(exampleResource) {
System.out.println("try block");
} catch(Exception e) {
System.out.println("catch block");
}
}
}
위와 같이 ExampleResource
클래스와 Main
클래스를 구현하면,
실행 결과로 위와 같은 결과가 나온다.
AutoClosable
인터페이스에서 오버라이드하여 구현한 .close()
메소드가 자동으로 호출되는 것을 볼 수 있다.
throws
키워드를 이용해 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘길 수 있다.void method() throws Exception {
// 예외가 발생하면 호출한 곳으로 떠넘긴다.
}
위와 같이 throws
를 통해 예외를 떠넘기는 메소드를 호출할 때는 해당 예외를 try ... catch
문으로 처리하거나 또 한번 throws
를 통해 예외를 떠넘기거나 해야 한다.
public class Main {
public static void main(String[] args) {
method();
}
public static void method() throws Exception {
System.out.println("method called");
}
}
위의 코드에서 컴파일러가 행동을 강제한다.
자바 API 도큐먼트 사이트에서는 위와 같이 throws
로 해당 메소드가 어떤 예외를 던지는지 잘 표기되어 있다.
main
메소드에서 throws
로 예외를 던져버리면, 사용자 입장에서는 갑자기 알 수 없는 메세지가 뜨며 프로그램이 종료되기 때문에 주의해야 한다.
Exception
클래스를 상속한다.RuntimeException
클래스를 상속한다.Exception
으로 끝내는 것이 관례이다.String
타입의 메세지를 받아 전달하기 위한 생성자catch
블록에서 이용할 수 있게 해준다.public class XXXException extends [ Exception | RuntimeException ] {
public XXXException() { }
public XXXException(String message) { super(message); }
}
throw new XXXException();
throw new XXXException("메세지");
catch(Exception e) { ... }
블록에서 넘어온 Exception e
변수를 이용한다.e.getMessage()
: Exception
클래스로 넘어온 예외 메세지를 가져올 수 있다.e.printStackTrace()
: 예외 발생 코드를 추적해서 모두 콘솔에 출력한다. 어떤 예외가 어디에서 발생했는지 상세하게 출력해준다.