본문 바로가기
Dev

Java 예외 처리(Exception) 와 예외 던지기 (throw, throws)

by Day0404 2021. 11. 7.
728x90
반응형

오늘은 자바(Java)에서 예외처리와 예외 던지기에 관하여 글을 작성해보려 합니다.

프로그램을 만들다 보면 수많은 에러가 발생하게 됩니다. 이러한 에러가 발생했을 때 그에 맞는 적절한 처리를 하게 된다면 더 안전한 프로그래밍을 할 수 있고 완성된 프로그램 또한 안정성이 높아질 것입니다.

 

예외(Exception)

Exception은 예외라는 뜻입니다. 프로그래밍에서 예외는 error라고 생각하시면 편합니다.

이 Exception이 발생하는 이유는 개발자의 실수나 예기치 못한 상황 등 여러 가지입니다.

기껏 만든 애플리케이션이 Exception이 발생하여 구동이 멈춘다거나 하면 상당히 곤란할 것입니다.

 

이러한 예외의 종류에는 크게 2가지가 있습니다.

컴파일 시 발생하는 컴파일 에러, 프로그램이 구동되는 중에 발생하는 런타임 에러가 있습니다.

컴파일 오류의 경우 대체로 문법상의 오류 때문에 많이 발생합니다.

런타임 오류의 경우 설계가 잘못되어 발생하는 경우가 많습니다.

 

그리고 자바에서는 이러한 Exception을 처리하기 위해 java.lang.Exception이라는 최상위 클래스를 제공합니다.

 

예외 처리

자바에서 기본적인 예외처리는 아래와 같이 try catch 문법을 통해 진행합니다.

try {
	// 실행되어야 할 로직
} catch (예외 클래스) {
	// 예외처리 코드
} finally {
	// 예외와 관계없이 무조건 실행되는 코드
}

try 블록에 실제 실행되어야 하는 코드가 들어가며 Exception이 발생할 가능성이 있는 코드가 들어갑니다.

catch 블록에는 Exception이 발생하면 실행되는 코드가 들어갑니다. 즉 예외처리를 하는 코드입니다.

finally 블럭에는 어떠한 예외가 발생하더라도 반드시 실행되어야 하는 코드가 들어가는 곳입니다.

 

코드를 아주 완벽하게 작성한다면 예외가 발생할 수 있는 상황이 줄어들 수는 있지만, 만약 사용자가 개발자의 의도와 다른 행동을 하여 예외가 발생하는 경우는 개발자가 미리 해당 상황에 대해 예외처리를 해줄 수 있습니다.

그렇게 하여 프로그램이 예기치 못한 상황에서 비정상적으로 종료되는 것을 막고 정상적으로 작동하게 할 수 있습니다.

이러한 예외적인 상황 발생에 대해 미리 대처하는 것을 예외처리라고 합니다.

 

public class Test {
	public static void main(String[] args) {
		int a = 2;
		int b = 0;
		int c = a / b;
		System.out.println(c);
	}
}

위 코드를 실행시키면 아래와 같이 오류가 발생합니다.

2를 0으로 나눌 수 없기 때문에 오류가 발생하게 됩니다.

이 코드를 다시 try catch 문을 통해 예외 처리하면 다음과 같습니다.

public class Test {
	public static void main(String[] args) {
		try {
			int a = 2;
			int b = 0;
			int c = a / b;
			System.out.println(c);
		} catch (ArithmeticException e) {
			e.printStackTrace();
		} finally {
			System.out.println("Finally");
		}
	}
}

printStackTrace() 메서드의 경우 어느 부분에서 예외가 발생했는지 로그를 보여줍니다.

위 코드를 실행시키면 아래와 같습니다.

처음에 예외 처리하지 않고 실행시킨 결과와 다를 게 없어 보입니다. 저는 그냥 printStackTrace로 예외의 로그를 확인하게만 해뒀기 때문에 그렇습니다.

만약 catch 문에 예외가 발생했을 때 다른 로직을 추가한다면 결과는 달라질 수 있습니다. 개발자가 작성하기 나름이니까요.

 

예외 던지기 (throw, throws)

throw, throws와 같은 예외 던지기의 경우 예전에 자바 공부를 할 때 저도 많이 헷갈렸던 부분입니다.

일단 throw의 경우 개발자가 의도적으로 예외를 발생시키는 것입니다.

throw라는 키워드를 이용하며, 주로 비즈니스 로직을 구현하는 과정 중 컴파일에는 문제가 없지만 해당 비지니스 로직이 개발자가 의도한 대로 통과하지 못했을 경우 고의로 예외를 발생시켜야 할 때 사용합니다.

public class Test {
	public static void main(String[] args) {
		int a = 2;
		int b = 0;
		divide(a,b);
	}

	public static int divide(int a, int b) {
		if (b == 0) {
			throw new ArithmeticException("0으로 나눌 수 없습니다.");
		}
		return a / b;
	}
}

위 코드를 실행시키면 아래와 같습니다.

물론 위 코드는 제가 throw를 사용하지 않아도 예외가 발생하게 됩니다. 만약 인자 값 a가 2인 경우 throw 키워드를 통해 강제로 예외 발생시킬 수도 있습니다.

이처럼 throw 키워드를 사용하면 개발자의 판단에 따라 강제로 예외를 발생시킬 수 있습니다.

 

 

throws의 경우 메서드 내에서 예외처리를 하지 않고 해당 메서드를 사용한 곳에서 예외 처리를 하도록 예외를 위로 던지는 것입니다. 예외를 전가하는 것 입니다.

public class Test {
	public static void main(String[] args) {
		int a = 2;
		int b = 0;
		try {
			divide(a,b);
		} catch (ArithmeticException e) {
			e.printStackTrace();
		}

	}

	public static int divide(int a, int b) throws ArithmeticException {
		if (b == 0) {
			throw new ArithmeticException("0으로 나눌 수 없습니다.");
		}
		return a / b;
	}
}

divide 메서드는 예외를 자신이 처리하지 않고 throws 키워드를 통해 자신을 호출한 main 메서드에게 책임을 전가했습니다. 

 

그래서 이 divide 메서드를 호출한 main 메서드에서 try catch 문을 통해 예외처리를 진행했습니다.

 

정리하자면 throw는 강제로 예외를 발생시키는 것이며 개발자의 판단에 따른 처리가 가능합니다.

throws는 자신을 호출한 메서드에게 책임을 전가하여 호출한 메서드에서 예외처리를 하도록 강요합니다.

 

throw를 사용하는 이유는 예외가 발생할 수 있는 코드가 있다는 것을 인지시키고 예외처리를 강요하며, 여러 가지 발생 가능한 예외들을 호출한 메서드에서 한 번에 처리할 수 있게 하여 관리를 용이하게 해 줄 수 있습니다.

 

쉽게 설명해보려고 노력했는데 조금이나마 도움이 됐으면 좋겠습니다.

혹시 틀린 부분이 있다면 댓글로 남겨주세요!

 

반응형

댓글