에러와 예외 (Error and Exception)
넓은 의미에서는 프로그램 실행 시 발생할 수 있는 모든 문제들을 에러라 부르기도 하지만, 에러와 예외는 프로그래밍에서 엄밀히 말하면 차이가 있다.
특히, 코드 실행(run-time) 시 발생할 수 있는 문제들을 크게 에러와 예외로 구분하고 있다.
에러(Error)의 경우, 한 번 발생하면 복구하기 어려운 수준의 심각한 문제를 의미하고, 대표적으로 메모리 부족인 OutOfMemoryError와 스택 오버플로우(StackOverflowError)가 있다.
예외(Exception)는 개발자의 잘못된 사용으로 인해 발생하는 에러는 상대적으로 약한 문제의 수준을 말한다. 즉, 개발자의 실수로 인해 발생하는 것이다. 이는 코드 수정을 통해 수습이 가능한 문제이다.
따라서 예외 처리는 코드 수정으로 해결이 가능한 문제를 처리하는 것이다.
예외 클래스의 상속 계층도
일반 예외 클래스(Exception)
런타임 시 발생하는 에러를 제외한 모든 Exception 클래스와 하위 클래스들을 가리킨다.
컴파일러가 코드 실행 전에 예외 처리 코드 여부를 검사하기 때문에 Checked 예외라 부르기도 한다.
주로 잘못된 클래스명(ClassNotFoundException)이나 데이터 형식(DataFormatException) 등 사용자 편의 실수로 발생하는 경우가 많다.
실행 예외 클래스(Runtime Exception)
런타임 시 발생하는 RuntimeException 클래스와 하위 클래스들을 카리 킨다.
컴파일러가 예외 처리 코드 여부를 검사하지 않기 때문에 Unchecked 예외라 부르기도 한다.
클래스 간의 형 변환 오류(ClassCastException), 배열의 범위를 벗어난 오류(ArrayIndexOutOfBoundsException), 값이 null인 참조 변수를 사용할 때 발생하는 오류(NullPointerException) 등이 있다.
예외 전가
예외 전가는 try-catch 문 외에 예외를 호출한 곳으로 다시 예외를 떠넘기는 것을 말한다.
메서드의 선언부 끝에 throws 키워드를 작성하여 발생할 수 있는 예외들을 쉼표로 구분하여 나열하는 것으로 작성한다.
public class ThrowsException {
public static void main(String[] args) {
try {
throwException();
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
static void throwException() throws ClassNotFoundException, NullPointerException {
Class.forName("예외 발생");
}
}
위 코드의 경우, throws 키워드를 사용하여 해당 예외를 발생한 메서드 안에서 처리하는 것이 아닌, 메서드를 호출한 곳으로 다시 떠넘긴다. 따라서 예외 처리 책임은 throwException 메서드가 아닌 main 메서드가 지게 된다.
예외를 의도적으로 발생
throws 키워드와 유사한 throw 키워드를 사용하면, 의도적으로 예외를 발생시킬 수 있다.
public class ThrowException {
public static void main(String[] args) {
try {
Exception intendedException = new Exception("의도적인 예외");
throw intendedException;
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
예기치 않게 발생할 수 있는 에러에 대응할 수 있도록 사전에 코드를 작성하여 예외 처리를 할 수 있다.
사용자 정의 예외
컴파일러가 체크하는 일반 예외로 선언하거나, 컴파일러가 체크하지 않는 실행 예외로 선언할 수 있다.
일반 예외로 선언 시 : Exception 상속
실행 예외로 선언 시 : RuntimeException 상속
[형태]
public class XXXException extends [Exception | RuntimeException] {
public XXXException() {} // 생성자 두 개
public XXXException(String message) {super(message);}
}
- 클래스 이름은 Exception으로 끝나는 것이 좋다.
- 필드, 생성자, 메소드 선언을 포함할 수 있지만 대부분 생성자 선언만 포함한다.
- 생성자는 두 개를 선언하는 것이 일반적이다.
- 하나는 매개 변수가 없는 기본 생성자, 다른 하나는 예외 발생 원인 (예외 메시지)를 전달하기 위해 String 타입의 매개 변수를 갖는 생성자이다.
예외 발생시키기
예외 발생 코드를 가지고 있는 메소드는 내부에서 try-catch 블록으로 예외 처리를 할 수 있지만, 대부분은 자신을 호출한 곳에서 예외를 처리하도록 throws 키워드로 예외를 떠넘긴다.
따라서 throws 키워드를 포함하고 있는 메소드를 호출한 곳에서는 try-catch 문으로 감싸는 식으로 예외 처리를 해줘야 한다.
[Account.java]
public class Account {
private long balance;
public Account() {}
public long getBalance() {
return balance;
}
public void deposit(int money) {
balance += money;
}
public void withdraw(int money) throws BalanceInsufficientException { // 예외 떠넘기기
if(balance < money)
throw new BalanceInsufficientException("잔고 부족! " + (money - balance) + "모자람");
balance -= money;
}
}
[AccountExample.java]
public class AccountExample {
public static void main(String[] args) {
Account account = new Account();
// 예금
account.deposit(10000);
System.out.println("예금액 : " + account.getBalance());
// 출금
try {
account.withdraw(30000);
} catch(BalanceInsufficientException e) {
String message = e.getMessage(); // 예외 메시지 얻기
System.out.println(message);
e.printStackTrace(); // 예외 추적 후 출력
}
}
}
예외를 발생시킬 때 String 타입의 메시지를 갖는 생성자를 사용하면 메시지는 자동적으로 예외 객체 내부에 저장된다. 예외 메시지는 catch 블록에서 getMessage() 메서드의 리턴값으로 얻을 수 있다.
printStackTrace()는 예외 발생 코드를 추적해서 모두 콘솔에 출력한다. 어떤 예외가 어디서 발생했는지 상세하게 출력한다. 주로 디버깅할 때 사용한다.
위의 예제에서 출금 시 withdraw() 메서드를 사용하므로 꼭 예외 처리가 필요하다. Account.java에서 발생된 예외는 AccountExample.java의 메서드 호출 위치로 예외가 떠넘겨지게 된다.
[참고 자료]
https://ittrue.tistory.com/140
[Java] 자바 예외 처리(Exception Handling) 개념 정리 및 활용
Intro 프로그래밍을 하고 실행하면 수많은 에러와 예외를 마주하게 된다. 에러 또는 예외가 발생하게 되면 프로그램은 의도한 대로 작동하지 않거나 실행을 비정상적으로 종료하기도 한다. 이러
ittrue.tistory.com
https://steady-hello.tistory.com/55
[Java] 자바의 예외 - Exception, RuntimeException 그리고 Error
자바의 Error, Exception에 대해 알아보려 한다. 지금부터 볼 내용은 포스팅 가장 아래의 레퍼런스 링크를 참조해서 읽어보면 좋겠다. 일단 Error와 Exception의 차이에 대해 알아보자. Throwable class Throwabl
steady-hello.tistory.com
https://kephilab.tistory.com/84
5. Java 자바 [예외 처리] - 사용자 정의 예외와 예외 발생 시키기, 예외 정보 얻기
자바 표준 API 에서 제공하는 예외 클래스만으로는 다양한 종류의 예외를 표현할 수 없다. 예) 은행 업무 처리에서 잔고 보다 많은 출금 요청 시, 오류!! 잔고 부족 예외는 표준 API에 존재하지 않
kephilab.tistory.com
'내배캠 > TIL' 카테고리의 다른 글
SQL 다중 조인 (0) | 2024.08.15 |
---|---|
SQL INSTR() 함수 (0) | 2024.08.14 |
IoC와 DI (2) | 2024.08.12 |
오브젝트와 의존관계 (0) | 2024.08.09 |
DTO, DAO, VO (0) | 2024.08.08 |