[Java] 예외처리 요약

eeminsu·2021년 10월 2일
0

자바의 정석을 통해 공부한 내용을 요약하였습니다.

1. 프로그램 오류

프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우가 있다.
이러한 결과를 초래하는 원인을 프로그램 에러 또는 오류라고 한다.

에러의 종류는 3가지가 있다.

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

컴파일 에러는 컴파일러가 알려준 에러들을 모두 수정하면 컴파일을 성공적으로 마칠 수 있다.
그렇다고 해서 런타임 에러가 발생하지 않는 것은 아니다.

런타임 에러를 방지하기 위해서는 프로그램 실행 도중 발생할 수 있는 모든 경우의 수를 고려하여 이에 대한 대비를 하는 것이 필요하다.

자바는 런타임 에러를 두 가지로 분류하였다.

Error 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
Exception 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류



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

자바에서는 Error와 Exception을 클래스로 정의하였다.
Error와 Exception 역시 Object클래스의 자손이다.

예외 클래스는 두 그룹으로 나뉜다.

  1. Exception클래스와 자손들(RuntimeException 제외)
  2. RuntimeException클래스와 자손들

RuntimeException 클래스들은 주로 프로그래머에 실수에 의해서 발생될 수 있는 예외들이다.
Exception 클래스들은 외부의 영향으로 발생할 수 있는 것들로서, 사용자들의 동작에 의해서 발생하는 경우가 많다.


3. 예외처리하기 - try, catch, finally

예외처리란?

  • 프로그램 실행 시 발생할 수 있는 예외를 대비한 코드를 작성하는 것
  • 예외 처리의 목적은 프로그램의 비정상 종료를 막고 정상적인 실행상태를 유지하는 것이다.

3-1. try, catch

예외처리를 하기위해서는 try-catch문을 사용한다.

try{
	// 예외가 발생할 가능성이 있는 코드를 작성한다.
}
catch (Exception e){
	// 예외가 발생했을 경우 이를 처리하기 위한 코드를 작성한다.
}

하나의 메서드 내에서 여러 개의 try-catch문이 사용될 수 있으며
try문과 catch문 안에서도 또 다른 try-catch문을 사용할 수 있다.
catch문 안에서 또 다른 try-catch문이 포함될 경우 같은 이름의 참조변수를 사용해서는 안된다.

3-2. try-catch문의 흐름

try블럭 내에서 예외가 발생할 경우

  • 발생한 예외와 일치하는 catch 블럭이 존재하는지 확인
  • 일치하는 catch 블럭 존재 시 해당 catch 블럭의 코드를 수행
  • 수행을 완료하면 try-catch문을 빠져나와 다음 문장을 수행
  • 일치하는 catch문이 없을 시 예외는 처리되지 못하고 비정상 종료

try블럭 내에서 예외가 발생하지 않을 경우

  • catch블럭을 거치지 않고 전체 try-catch문을 빠져나와 다음 문장을 수행

3-3. 예외 클래스의 메서드

예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨있다.

printStackTrace() 예외발생 당시의 호출스택에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
getMessage() 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.

class ExceptionEx08 {
	public static void main(String args[]) {
		try {
			System.out.println(0/0); // ArithmeticException 예외 발생
		} catch (ArithmeticException ae)	{
			ae.printStackTrace();
			System.out.println("예외메시지 : " + ae.getMessage());
		}
	}
}



3-4. finally

finally블럭은 예외의 발생여부에 상관없이 실행되어야할 코드를 포함시킬 목적으로 사용된다.

try{
	// 예외가 발생할 가능성이 있는 코드 작성
}
catch (Exception e){
	// 예외 처리를 위한 코드 작성
}
finally{
	// 예외 발생 여부와 관계없이 항상 수행되어야하는 코드 작성
        // try-catch문의 마지막에 위치
}

예외가 발생한 경우에는 try→catch→finally순으로 실행
예외가 발생하지 않은 경우에는 try→finally순으로 실행

try블럭에서 return문이 실행되는 경우에도 finally블럭의 문장들이 먼저 실행된 후에 메서드를 종료한다.
catch문에서 또한 마찬가지다.


4. 예외처리하기2 - throws

try-catch문을 사용하는 것 이외에 예외를 메서드에 선언하는 방법이 있다.
예외를 떠넘기는 것이다

메서드에 예외를 선언하려면 선언부에 키워드 throws를 사용하여 발생할 수 있는 예외를 적어준다.
예외가 여러개일 경우 쉼표로 구분한다.

void method() throws Exception1, Exception2 .... {
// 메서드 내용
}

만약 Exception클래스를 메서드에 선언하면 모든 종류의 예외가 발생할 수 있는 메서드라는 뜻이다.
Exception클래스는 예외클래스의 최고 조상 클래스이기 때문에 자손타입의 예외까지도 발생할 수 있다.
오버라이딩할 때 선언된 예외의 개수가 아니라 상속관계까지 고려해야 한다.

이처럼 자바에서는 메서드를 작성할 때 메서드 내에서 발생할 수 있는 예외를 선언부에 명시하여
사용하는 쪽에서 이에 대한 처리를 강요하도록 하기 때문에 견고한 프로그램 코드를 작성할 수 있도록 도와준다.

위에서도 언급했다싶이 사실 throws를 명시하는 것은 예외를 처리하는 것이 아닌 자신을 호출한 메서드에게 예외를 떠넘기는 것이다.
이런식으로 계속해서 메서드를 따라 예외가 전달되다가 마지막 main메서드를 만나서까지도
예외가 처리되지 않는다면 프로그램은 비정상 종료를 하게 된다.
결국 마지막에는 try-catch문을 사용하여 예외를 처리해야한다.

throws를 사용하여 예외처리를 여러 메서드가 분담하여 처리할 수 있다.


profile
안되면 될 때까지

0개의 댓글