본문 바로가기
CS/JAVA

[JAVA] 예외 클래스

728x90

 

 

 


예외(Exception)란?

 

Java 프로그램에서 실행 오류가 발생하는 경우는 크게 에러(Error)와 예외(Exception) 두 가지로 나눌 수 있다. 에러는 JVM 실행 자체에 문제가 발생한 것으로 ThreadDeath, JVM 오작동 등 프로그램 내에서 다룰 수 없는 부분이다. 예외는 개발자나 사용자의 잘못으로 인해 프로그램에 발생한 오류로 프로그램 내에서 처리할 수 있는 부분이다. Java는 예외 또한 클래스를 통해 관리한다. Object를 상속받는 Throwable 클래스가 있고, 모든 예외 클래스들은 Throwable 클래스를 상속받는다. 계층 구조는 다음과 같다. 

 

 

 

 

 


Checked Exception

 

Exception 클래스의 하위 클래스 중 RuntimeException을 제외한 나머지 예외 클래스들은 프로그램 내에서 처리되지 않으면 컴파일 시 오류가 발생한다. 코드에 이상이 없더라도 예외 발생 가능성이 있는 부분은 반드시 처리해주어야 하며 컴파일 시 확인 가능하기 때문에 Checked Exception이라고도 불린다. 대표적인 Checked Exception은 다음과 같다.

 

java.lang.ClassNotFoundException: 유효하지 않은 클래스 로드를 시도할 때 발생

java.io.IOException: 입/출력 처리에 실패할 때 발생
- java.io.EOFException
- java.io.FileNotFoundException
              ⋮

java.sql.SQLException: 데이터베이스 액세스와 관련하여 발생

 

 

 


RuntimeException (UnChecked Exception)

 

RuntimeException과 그 하위 Exception들은 컴파일 시에는 체크되지 않고 실행 중 발생하는 예외이다. 따라서 Unchecked Exception이라고도 불리며, 이 외의 나머지 예외들은 처리되지 않으면 컴파일 시 오류가 발생하기 때문에 Checked Execption이라고도 불린다. 대표적인 RuntimeException은 다음과 같다.

 

java.lang.NullPointerException: 멤버 변수나 메소드 등, null 객체를 참조하려 할 때 발생한다. 

java.lang.ArthmeticException: 숫자를 0으로 나누는 등, 산술 연산에서 예외 조건이 생길 때 발생한다.

java.lang.IndexOutOfBoundsException: 객체의 인덱스 범위를 넘어서 참조할 때 발생한다.
- java.lang.ArrayIndexOutOfBoundsException
- java.lang.StringIndexOutOfBoundsException

java.lang.NumberFormatException: 메소드가 문자열을 숫자 형식으로 변환할 수 없을 때 발생한다. 

java.lang.ClassCastException: 클래스 간 잘못된 형변환을 하는 경우 발생한다.

java.util.NoSuchElementException: Queue 등의 객체의 비어있는 공간에서 값을 꺼내려할 때 발생한다.

 

 

 


 예외 처리 (try-catch & throws)

 

Java에서는 try-catch문을 사용하거나 메소드를 호출한 곳으로 예외를 전가함으로써 예외를 처리할 수 있다. 

 

 

 


◾ try - catch 구문

 

코드 실행 중 예외가 발생할 가능성이 있는 부분을 try 블록으로 감싸준다. 만약 예외가 발생한다면 catch 블록에서 이를 감지하여 추가 처리를 하고 예외가 발생하지 않는다면 catch 블록은 실행되지 않는다. finally 블록은 선택사항이며 항상 실행되는 블록이다. 

 

public class ExceptionTest {

	static void divide(int a, int b) {
		try {
			System.out.println(a / b);
		} catch (ArithmeticException e) {
			System.out.println("0으로는 못나눔!");
		} finally {
			System.out.println("항상 실행!");
		}
	}

	public static void main(String[] args) {
		divide(3,0);  // 0으로는 못나눔! finally!
		divide(3,3);  // 1 finally!
	}
}

 

위 코드에서 divide 메소드는 정수를 입력받고 나눈 결괏값을 출력한다. 만약 divide(3, 0)을 호출하면 0으로 나눌 수 없기 때문에 java.lang.ArithmeticException이 발생한다. 하지만 위와 같이 try - catch 블록을 통해 예외를 처리한다면 예외가 발생하더라도 프로그램이 종료되지 않는다. 

 

 

 


◾ throws

 

try - catch 블록으로 예외를 처리하지 않고 throws 예약어를 통해 메소드를 호출한 곳으로 예외를 전가할 수도 있다.

 

public class ExceptionTest {

	static void divide(int a, int b) throws ArithmeticException {
		System.out.println(a / b);
	}

	public static void main(String[] args) {

		try {
			divide(3, 0);   // 0으로는 못나눔! finally!
			divide(3, 3);   // 1 finally!
		} catch (ArithmeticException e) {
			System.out.println("0으로는 못나눔!");
		} finally {
			System.out.println("항상 실행!");
		}
	}
}

 

위 코드에서 divide 메소드는 java.lang.ArithmeticException이 발생한다면 이를 호출자에게 전가한다. 따라서 divide 메소드를 호출하기 위해서는 반드시 호출 부분을 try - catch 블록으로 처리해주어야 한다. 만약 main에서 예외를 throws 한다면 발생하는 예외를 JVM에게 전가하는 의미이므로 별다른 처리를 하지 않은 것과 같은 모습을 보인다.

 

 

 


📝 요약

◾ Java에서는 Exception 또한 클래스로 처리하며 크게 CheckedException과 UnCheckedException(RuntimeException)으로 나뉜다. 

◾ Exception은 try - catch 블록을 통해 처리하거나 throws를 통해 전가할 수 있으며 CheckedException은 처리하지 않으면 컴파일이 되지 않는다.

 

 

 


📃 Ref

728x90
반응형

'CS > JAVA' 카테고리의 다른 글

[JAVA] JVM 구조와 메모리  (0) 2021.07.26
[JAVA] Wrapper 클래스  (0) 2021.07.25
[JAVA] 객체와 클래스, 그리고 인스턴스의 차이  (0) 2021.07.24