에러( Error )와 예외( Exception )
자바에서 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용 프로그램 실행 오류가 발생하는 것을 에러라고 합니다.
그리고 그 외 프로그램 자체에서 발생하는 오류를 예외라고 합니다.
예외의 종류와 발생 경우를 알아보겠습니다.🧐
예외 (Exception)
사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 예외라고 합니다.
예외가 발생되면 프로그램은 곧바로 종료됩니다.💢
프로그램이 종료되는 것을 막기 위해 예외를 적절하게 사용해야 합니다.
예외 처리를 적절하게 하면 프로그램이 종료되지 않고 정상 실행상태로 유지 가능합니다. 🩹
또한 자바에서는 예외 발생 가능성이 높은 코드 컴파일할 때, 예외 처리 유무를 확인합니다.
만약 예외 처리 코드가 없다면 컴파일 되지 않습니다.
- 일반 예외 (Exception)
프로그램 실행시 예외가 발생할 가능성이 높기 때문에 자바 소스를 컴파일하는 과정에서
해당 예외 처리 코드가 있는지 검사합니다. 예외 처리 코드가 없다면 오류가 발생합니다!
컴파일 과정에서 파악 가능한 예외
- 실행 예외 (Runtime Exception)
실행 시 발생되는 예외로, 예측할 수 없어 갑자기 발생하기 때문에 컴파일 과정에서 예외 처리 코드가 있는지 검사할 수 없습니다.
컴파일 과정에서 파악할 수 없는 예외
자바에서의 예외 처리, 예외 클래스

자바에서는 예외를 클래스로 관리합니다.
JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당하는 예외 클래스 객체를 생성합니다.
그리고 예외 처리 코드에서 예외 객체를 활용할 수 있도록 합니다.
모든 예외 클래스는 java.lang.Exception 클래스를 상속해서 구현합니다.
예외 클래스 분류
RuntimeException 클래스를 기준으로 일반 및 실행 예외 클래스를 구분합니다.

RuntimeException의 하위 클래스가 아니면 일반 예외 클래스이고, 하위 클래스이면 실행 예외 클래스입니다.
실행 예외 종류
NullPointerException
자바 프로그램에서 가장 빈번하게 발생하는 실행 예외입니다.
객체의 참조가 없는 상태로, null값을 갖는 참조 변수로 객체의 접근 연산자인 도트(.)를 사용했을 때 발생합니다.
객체가 없는 상태에서 객체를 사용하려 했기 때문에 발생됩니다.
ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과할 경우 실행 예외인
java.lang.ArrayIndexOutOfBoundsException이 발생됩니다.
배열 값을 읽기 전에 배열의 길이를 조건문을 통해 먼저 확인하는 것이 좋습니다.
NumberFormatException
문자열에 숫자로 변환할 수 없는 문자가 포함된 경우 java.lang.NumberFormatException이 발생합니다.
ClassCastException
타입 변환(Casting)은 상위 클래스와 하위 클래스 간에 할 수 있습니다.
구현 클래스와 인터페이스 간에도 타입 변환할 수 있습니다.
타입 변환에 있어 이러한 관계가 아니라면 변환이 불가능하기 때문에 ClassCastException을 발생시킵니다.
그렇기 때문에 타입 변환할 때는 조건문과 instanceof 연산자를 활용하여 미리 확인하는것이 좋습니다.
예외 처리하는 방법
try - catch - finally 블록
try - catch - finally 블록을 생성자 및 메소드 내부 작성해서
일반 예외와 실행 예외가 발생할 경우에 대해서 예외처리를 합니다.
try {
// 예외 발생 가능 코드
} catch (예외 클래스 e) {
// 예외 처리
} finally {
// 항상 실행
}
1. try 블록에 예외가 발생될 수 있는 코드를 작성합니다.
2. try 블록의 모든 코드가 예외 발생 없이 정상 실행되면 catch 블록의 코드는 실행되지 않습니다.
반면, try 블록에서 예외가 발생하면 해당 실행문 까지만 실행하고 try 블록을 빠져나가 catch블록의 예외처리 코드를 실행합니다.
3. finally 블록의 코드는 예외 발생과 상관없이 항상 실행됩니다.
try 블록과 catch 블록에 return문이 있더라도 실행됩니다.
* finally 블록은 생략 가능
예외 처리 시 예외 클래스별 분기하기
try {
ArrayIndexOutOfBoundsException 발생!
NumberFormatException 발생!
} catch (ArrayIndexOutOfBoundsException e) {
예외 처리1
} catch (NumberFormatException e) {
예외 처리2
}
try 블록 내부는 다양한 종류의 예외가 발생할 수 있습니다.
발생하는 예외별로 예외 처리 코드를 다르게 하려면 다중 catch 블록을 작성하면 됩니다.
try 블록에서 에외가 발생하면 즉시 catch 블록을 실행하도록 되어있습니다.
catch 블록이 여러 개라고 해도 단 하나의 catch 블록만 실행됩니다.
try 블록에서 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 문으로 이동하기 때문!
즉 위 코드에서는 예외처리1만 수행하게 됩니다.
다중 catch 블록을 작성할 때 주의할 점
상위 예외 클래스가 하위 예외 클래스 보다 아래 위치해야 합니다.
try 블록에서 예외가 발생했을 때 예외를 처리해 줄 catch 블록은 위에서부터 차례대로 검색하기 때문에
만약 상위 예외 클래스의 catch 블록을 위에 작성했다면,
아래에 작성된 하위 예외 클래스는 실행될 수 없습니다.
* 하위 예외는 상위 예외를 상속했기 때문에 상위 예외 타입도 되기 때문입니다.
catch(Exception e) {
System.out.println("실행에 문제가 있습니다.");
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
}
// 결과: 실행에 문제가 있습니다.
만약 catch문이 이렇게 구성되어있다고 한다면 개발자는 더욱 상세한 이유를 알고 싶을 것입니다.
하지만 더 위에 위치한 상위클래스 Exception클래스가 처리 되기 때문에 정확한 문제를 알 수 없습니다.
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
} catch(Exception e) {
System.out.println("실행에 문제가 있습니다.");
}
그래서 이렇게 순서를 바꿔주는 것이 좋습니다.
throws 키워드
throws는 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를
호출 한 곳으로 넘기는 역할을 합니다.
리턴타입 메소드이름(매개변수,...) throws 예외클래스1, 예외클래스2,...{
...
}
떠넘길 예외 클래스에 대해 종류별로 throws 뒤에 작성하는 것이 일반적이지만, 다음과 같이 throws Exception만으로 모든 예외를 간단히 떠넘길 수 있습니다.
리턴타입 메소드이름(매개변수,...) throws Exception {
...
}
throw 키워드가 붙어 있는 메소드를 호출할 땐 try 블록 내에서 호출 해야합니다.
또한, throws 키워드가 붙어 있는 메소드를 호출하고 또 throws 키워드를 사용해서 다시 예외를 떠넘길 수 있습니다.

throws를 계속 하다보면 main() 메소드에서도 예외를 떠넘길 수 있는데 결국 JVM이 최종적으로 콘솔에 출력하는 것으로 예외를 처리하게 됩니다.
이 방법은 프로그램 사용자가 자바의 예외 내용을 확인한 뒤 프로그램이 종료되는 현상이 발생하기 때문에 좋지 못한 방법입니다. 따라서 main()에서 try-catch 블록으로 예외를 최종 처리하는것이 좋습니다.
예외가 나오면 바로 처리하지 않고 throws로 넘기는 이유가 무엇일까❓
굉장히 많은 이유가 있었지만 대표적으로 에러 처리의 중앙화라고 합니다.
에러 처리 코드가 전체 코드에 분산되어 있으면 가독성과 유지관리가 어려워지기 때문에 중앙으로 에러를 모아서 처리하기 위함이라고 합니다❗
🔆느낀점🔆
옛날에 자바를 배울때 throws 에 대해서 매우 어려워했었고 결국 이해하지 못해
현재의 저에게 throw 해버렸습니다.
사실 지금 글을 쓰면서도 throw에 대해서 한참 찾아보았습니다ㅠㅠ😭
하지만 이번엔 완벽하게 이해하기 위해 노력했고 이젠 정확히 알게되어 기쁩니다!😀
앞으론 모르는 것이 있으면 미루지 않겠다고 다시 한번 다짐했고
오늘 끈기있게 throws에 대해서 집착한 저에게 칭찬하며 글을 끝내고 싶습니다!👏👏👏👏👏
'🧮Programming > Java' 카테고리의 다른 글
| [Java] 컬렉션 프레임워크 (1) | 2024.02.07 |
|---|---|
| [Java] 추상 클래스, 인터페이스 (1) | 2024.02.06 |
| [Java] 상속, 다형성 (0) | 2024.02.06 |
| [Java] 패키지와 접근 제한자 (0) | 2024.02.06 |
| [Java] 객체와 클래스 (0) | 2024.02.06 |