728x90
1. 프로그램 오류
2. 에러 종류
3. 예외 클래스의 계층 구조
4. 예외 구분

5. 예외처리
6. 멀티 catch블럭
7. 예외 발생시키기
8. finally 블럭
9. 예외 되던지기

 

1. 프로그램 오류

에러(error) 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
메모리 부족(OutOfMemoryError)나 스택오버플로우(StackOverflowError) → 발생하면 복구할 수 없는 심각한 오류
예외(exception) 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류

 

2. 에러 종류

컴파일 에러 컴파일 시에 발생하는 에러
런타임 에러 실행 시에 발생하는 에러
논리적 에러 실행은 되지만, 의도와 다르게 동작하는 것

※ 컴파일..?

 컴파일러가 소스코드(*.java)를 컴파일을 성공적으로 마치고 나면, 클래스 파일(*.class)이 생성

 생성된 클래스 파일을 실행할 수 있게 되는 것.

 

3. 예외 클래스의 계층 구조

간략화된 예외 클래스 계층 구조

  • 모든 클래스의 조상은 Object클래스
  • 모든 예외의 최고 조상은 Exception
Exception 클래스들 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
RuntimeException 클래스들 프로그래머의 실수로 발생하는 예외

 

4. 예외 구분

  Checked Exception Unchecked Exception
처리여부 반드시 예외를 처리해야 함 명시적인 처리를 강제하지 않음
확인시점 컴파일 단계 실행 단계
예외발생 시 트랜잭션 처리 roll-back 하지 않음, commit까지 완료 roll-back 함
대표 예외 Exception의 상속받는 하위 클래스 중 Runtime Exceptiondmf 제외한 모든 예외
- IOException
- SQLException
RuntimeException 하위 예외
- NullPointerException
- IllegalArgumentException
- IndexOutOfBoundException
- SystemException

# 참고 사이트 : https://devlog-wjdrbs96.tistory.com/351

출처 : https://devlog-wjdrbs96.tistory.com/351

 

5. 예외처리

  • 정의 : 프로그램 실행 시, 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것
  • 목적 : 프로그램의 비정상 종료 방지 및 정상적인 실행상태 유지
  • 방법 : try-catch문 사용
    • 처리 : try블럭 내에 예외가 발생한 경우, 발생한 예외와 일치하는 catch블럭이 있는지 확인 후 일치하는 catch블럭 내의 문장들을 수행하고 전체 try-catch문을 빠져나가서 그 다음 문장을 계속해서 수행 (만일, 일치하는 catch블럭을 찾지 못하면, 에외는 처리되지 못한다.)
  • 예외처리 출력 메소드
    • printStackTrace() : 예외발생 당시의 호출스택(CallStack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
    • getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.
    • 참고 > 
    • 예외처리 출력 메소드 예시
class ExceptionEx8 {
	public static void main(String args[]){
    	System.out.println(1);
        try {
        	System.out.println(2);
            System.out.println(0/0);	// 예외발생
            System.out.println(3);		// 실행되지 않음
        } catch (ArithmeticException ae) {
        	ae.printStackTrace();
            System.out.println("예외메시지 : " + ae.getMessage());
        } // try-catch의 끝
        System.out.println(4);
    } // main 메서드의 끝
}

/**
 * 실행결과
 * 1
 * 2
 * java.lang.ArithmeticException: / by zero
 *		at ExceptionEx8.main(ExceptionEx8.java: 7)
 * 예외메시지 : / by zero
 * 4
 */

※ 예외 처리를 하지 않으면, 프로그램은 비정상적으로 종료되며, 처리되지 못한 예외는 JVM의 예외처리기(UncaughtExceptionHandler)가 받아서 예외의 원인을 화면에 출력

 

6. 멀티 catch블럭

// 여러 catch블럭
try {
	...
} catch (ExceptionA ea) {
	ea.printStackTrace();
} catch (ExceptionB eb) {
	eb.printStackTrace();
}

// '멀티 catch블럭' 으로 개선
try {
	...
} catch (ExceptionA | ExceptionB e) {
	e.printStackTrace();
}

▶ 여러 catch 블럭을 '|' 기호를 통해 멀티 catch블럭으로 사용할 수 있다.

다만! catch (ParentException | ChildException e) { .. } 는 조상과 자손의 관계에 있다면 컴파일 에러 발생한다.

불필요한 코드는 제거하라는 의미에서 에러가 발생하며, 이는 catch (ParentException e) { .. } 와 같이 조상 클래스만 사용하면 된다.

▶ 또한, 멀티 catch블럭에서는 참조변수 e로 공통 분모인 조상 예외 클래스에 선언된 멤버만 사용가능하다.

 

7. 예외 발생시키기

// 1. 연산자 new를 이용해 발생시키려는 예외 클래스의 객체를 만듦
Exception e = new Exception("고의로 발생시킴");

// 2. 키워드 throw를 이용해서 예외를 발생
throw e;

// 1,2를 한 줄로 줄여서 사용 가능
throw new Exception("고의로 발생시킴");

 

8. finally 블럭

예외 발생 여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용

try {
	// 예외가 발생할 가능성이 있는 문장 삽입
} catch (Exception e) {
	// 예외 처리를 위한 문장
} finally {
	// 예외 발생 여부에 관계없이 항상 수행되어야하는 문장 삽입
}
  • 예외 발생한 경우 : try → catch → finally
  • 에외가 발생하지 않은 경우 : try → finally

 

9. 예외 되던지기

예외가 발생할 가능성이 있는 메서드에서 try-catch문을 사용해서 예외를 처리해주고, catch문에서 필요한 작업을 행한 후에 throw문을 사용해서 예외를 다시 발생시킨다.

class ExceptionEx17 {
	public static void main(String[] args){
    	try {
        	method1();
        } catch (Exception e) {
        	System.out.println("main메서드에서 예외가 처리되었습니다.");
        }
    } // main메서드의 끝
    
    staic void method1() throws Exception {
    	try {
        	thorw new Exception();
        } catch (Exception e) {
        	System.out.println("method1메서드에서 예외가 처리되었습니다.");
            throw e; // 다시 예외를 발생시킨다.
        }
    } // method1메서드의 끝
}

/**
 * 실행결과
 * method1메서드에서 예외가 처리되었습니다.
 * main메서드에서 예외가 처리되었습니다.
 */

method1()과 main메서드 양쪽의 catch블럭이 모두 수행되었음을 실행결과를 통해 알 수 있다.

method1()의 catch블럭에서 예외를 처리하고도 throw문을 통해 다시 예외를 발생시켰으며 이 예외를 main메서드에서 한번 더 처리했다.

※ 참고로, 반환값이 있는 return 문의 경우, catch블럭에도 return문이 있어야 한다. 예외가 발생했을 경우에도 값을 반환해야하기 때문.

또는, catch블럭에서 예외 되던지기를 해서 호출한 메서드로 예외를 전달하면 return문이 없어도 된다.

더보기
static int method1)( throws Exception { // 에외를 선언해야함
	try {
    	System.out.println("method1()이 호출되었습니다.");
        return 0;	// 현재 실행 중인 메서드를 종료한다.
    } catch (Exception e) {
    	e.printStackTrace();
        // return 1; // catch블럭 내에도 return문이 필요하다.
        throw new Exception(); // return문 대신 예외를 호출한 메서드로 전달
    } finally {
    	System.out.println("method1()의 finally블럭이 실행되었습니다.");
        // return 2; // finally블럭 내에도 return문을 사용할 수 있으며, 최종적으로 try-catch의 return문이 아닌, finally 블럭 내의 return문의 값이 반환된다.
    }
} // method1메서드의 끝

참고 도서 : Java의 정석(3rd edition)[도우출판, 남궁성]

728x90

+ Recent posts