예외와 에러의 차이점은 무엇일까?
compile time(우리가 짠 코드인 human language를 machine language로 바꿔주는 과정)에 발생하는 것이 에러이고 compile이 끝난 후 실행하는 runtime에 발생하는 것이 exception이다. 따라서 exception이 발생했다는 것은 compile time은 통과했고, eclipse에서 빨간 줄이 뜨지 않았다는 의미이다. 코드 상으로는 문제가 없지만 keyboard 입력 등으로 값에 의해 발생하는 것이 예외이다. 예외는 표준 예외와 사용자 정의 예외로 나뉜다.
① 표준 예외
표준 예외는 sun에서 이미 알고 있는 예외로, 예외를 처리하는 클래스까지 정의되어 있다. try 블록에 예외가 발생할 가능성이 있는 코드를 작성하면, 예외를 만났을 때 가상머신이 자동으로 멈춘다. 가상머신이 해당 예외를 처리하는 클래스를 가져와서 인스턴스를 생성한 후 현재 만난 예외, 즉 현재 생성된 인스턴스와 같은 클래스 이름이 적힌 catch 절로 이동한다.
- e.getMessage() : 현재 예외가 왜 발생했는지 이유를 출력해 준다.
- e.printStackTree() : 이유를 찍어주고, trace 기능을 통해 예외가 발생된 지점을 추적해서 알려준다.
try 블록이 길어지면 여러 개의 에러가 발생할 가능성이 커진다. 이때는 하나의 try 블록에 여러 개의 catch 절을 붙인다. catch 절이 여러 개 있으면 적힌 순서대로 찾아가서 한 번에 하나씩만 실행하고, 실행되었으면 밑으로 내려가지 않는다.
그런데 프로그램을 개발할 때 내가 모르는 예외가 뜨면 어떻게 할까? 모든 예외 클래스의 이름을 알고 있어야 할까?
예외 처리에서 최상위 super는 throwable interface이다. 따라서 무조건 가장 마지막 catch 절에는 Throwable e를 적는다. 이렇게 하면 어떤 예외가 인스턴스로 생성되더라도 Throwable에서 다 걸린다. (Throwable의 sub 클래스인 Exception을 사용해도 된다.)
② 사용자 정의 예외
사용자 정의 예외 처리는 sun에서 모르는 예외로, 개발자들 사이에서 정의된 규칙에 의해 발생하는 예외이다. sun에서 모르는 예외이기 때문에 개발자가 직접 예외를 처리하는 클래스를 만들어야 한다.
Step 1. 예외를 처리하는 클래스 작성
Exception class를 상속받아 생성자에 super(현재 클래스보다 한 단계 높은 super class의 생성자를 호출하는 메서드)를 사용하여 적어주고 싶은 메시지를 적으면 된다. 가독성을 위해 클래스 이름에 Exception을 붙이는 것이 좋다.
class XXXException extends Exception {
public XXXException() {
super("XXX하여 예외가 발생하였습니다.");
}
}
Step 2. 예외 발생 시 인스턴스 생성 & 생성된 인스턴스를 JVM에 전달
<접근 제한자> <반환 타입> <메서드 이름()> throws XXXException {
if (예외가 발생하는 조건)
XXXException exp = new XXXException();
throw exp;
}
}
[throws vs throw]
throws : A throws B는 A에서 B 예외가 발생하면 A 메서드를 호출한 곳에서 예외를 처리할 것이라는 의미이다. throws는 메서드 뒤에만 붙으며 호출되는 메서드(A) 안에서는 try - catch를 적지 않는다. 호출되는 메서드(A) 안에서 예외를 처리하면 호출되는 모든 메서드 안에 try - catch를 적어야 하지만, 메서드 뒤에는 throws만 적고 호출한 곳에서 예외를 처리하면 try – catch 문 하나로 모든 예외를 처리할 수 있기 때문이다.
throw : throw는 가상머신에게 생성된 인스턴스를 전달하는 문법이다.
[try – catch - finally]
try 블록에서 발생된 예외가 없으면 catch 절을 실행하지 않고 finally를 실행한다. 예외가 발생하면 catch를 실행한 후 finally를 실행한다. 따라서 finally 영역은 예외가 있든 없든 무조건 실행되기 때문에 이 영역에 종료코드를 넣는 경우가 많다.
ex) 중간에 예외가 발생하면 코드가 멈추기 때문에 finally를 사용하여 사용한 자원이나 DB 연결 등을 다 닫고 나간다.
[main(String[] args) throws XXXException]
main method에 throws를 사용하여 try – catch 없이 예외를 처리하는 케이스가 있다. 이 경우 main에서 throws 뒤에 적은 예외가 발생하면, 그 예외는 main에서 처리하지 않고 main을 호출하는 곳, 즉 가상 머신에서 예외를 처리하겠다는 의미이다.
'JAVA' 카테고리의 다른 글
[JAVA] Chapter 15. Wrapper Class (0) | 2023.07.20 |
---|---|
[JAVA] Chapter 14. VO Class (0) | 2023.07.19 |
[JAVA] Chapter 12. Abstract & Interface (2) (0) | 2023.07.17 |
[JAVA] Chapter 12. Abstract & Interface (1) (0) | 2023.07.16 |
[JAVA] Chapter 11. Inheritance (3) (0) | 2023.07.15 |
댓글