프로그래밍/JAVA

[JAVA] 메소드에 예외 선언하기 (throws)

리신 2022. 11. 21. 23:24
반응형

예외를 처리하는 방법에는 지금까지 배워 try-catch문을 사용하는 것 외에, 예외를 메서드에 선언하는 방법이 있다.

 

메서드에 예외를 선언하려면, 메서드의 선언부에 키워드 throws를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어주기만 하면 된다. 그리고 예외가 여러 개일 경우에는 쉼표(,)로 구분한다.

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

 

✅ 참고

예외를 발생시키는 키워드 throw와 예외를 메서드에 선언할 때 쓰이는 throws를 잘 구분하자.

 

그리고 메서드의 선언부에 예외를 처리함으로써 메서드를 사용하려는 사람이 메서드의 선언부를 보았을 때,

메서드를 사용하기 위해서는 어떠한 예외들이 처리되어야 하는지 쉽게 알 수 있다.

 

자바에서는 메서드를 작성할 때 메서드 내에서 발생할 가능성이 있는 예외를 메서드의 선언부에 명시하여 이 메서드를 사용하는 쪽에서는 이에 대한 처리를 하도록 강요하기 때문에, 프로그래머들의 짐을 덜어 주는 것은 물론이고 보다 경고한 프로그램 코드를 작성할 수 있도록 도와준다.

 

정리

throws는 한마디로 예외를 위임하는 것이다. (예외 처리를 다른 쪽으로 떠넘김)

그리고 예외를 전달받은 메서드가 또다시 자신을 호출한 메서드에게 전달할 수 있으며,

이런 식으로 계속 호출 스택에 있는 메서드들을 따라 전달되다가 제일 마지막에 있는 main메서드에서도 예외가 처리되지 않으면, main메서드마저 종료되어 프로그램이 전체가 종료된다.

 

글로만 보아서는 이해가 되지 않을 수 있으니 예제로 한번 보자!

💎예제💎

class ExceptionEx12 {
	public static void main(String[] args) throws Exception{
    	method1(); // 같은 클래스내의 static멤버이므로 객체생성없이 직접 호출가능.
    }
    
    static void method1() throws Exception {
    	method2();
    }
    
    static void method2() throws Exception {
    	throw new Exception();
    }
}

위 코드의 실행결과를 보면, 프로그램의 실행 도중 java.lang.Exception이 발생하여 비정상적으로 종료했다는 것과 예외가 발생했을 때 호출 스택의 내용을 알 수 있다.

1. 예외가 발생했을 때, 모두 3개의 메서드( main, method1, method2)가 호출 스택에 있었으며,
2. 예외가 발생한 곳은 제일 윗줄에 있는 method2()라는 것과
3. main메서드가 method1()을, 그리고 method1()은 method2()를 호출했다는 것을 알 수 있다.

이 처럼 예외처리를 떠넘기기만 하고 처리해주는 곳은 없기 때문에 main메서드가 종료되어 프로그램이 예외로 인해 비정상적으로 종료가 되었다.

그러면 throws로 예외를 떠넘기더라도 어디 한 군데에서는 예외처리를 해줘야 한다는 말이다.

 

그러면 예외처리를 throws를 써서 다른 곳에서 처리해주기 vs  메서드 내에서 예외를 처리해주기 어떤 것이 좋은 걸까?

→ 답은 상황에 따라 다르다는 것이다!

 

메소드 내에서 직접 처리해야 한다면 try-catch를 사용하고 다른 곳에서 해야 한다면 throws를 사용한다.

하지만 그래서 언제 사용하는 거냐고!!?

감이 잡히지 않을 수 있으니 예제로 한번 알아보자!

 

💎예제💎

import java.io.*;
public class ExceptionEx15 {
	public static void main(String[] args){
		// command line에서 입력받은 값을 이름으로 갖는 파일을 생성한다.
		File f = createFile(args[0]);
		System.out.println(f.getName() + "파일을 성공적으로 생성");
    }
	static File createFile(String fileName) {
		try {
			if(fileName == null || fileName.equals(""))
				throw new Exception("파일 이름이 유효하지 않음");
		} catch (Exception e) {
			// file이름이 부적절한 경우 "제목없음.txt"
			fileName = "제목없음.txt";
		}finally {
			File f = new File(fileName);
			createNewFile(f);
			return f;
		}
	}
	
	private static void createNewFile(File f) {
		try {
			f.createNewFile();
		}catch (Exception e) {}
	}
}

위 코드를 보면 사용자에게 파일 이름의 입력값을 받고 파일을 생성해준다.

하지만 파일의 이름이 NULL 이거나 "" 빈 값일 경우 "제목 없음. txt"로 파일을 생성해준다.

 

코드를 보면 위 내용처럼 처리해야 할 경우 createFile 메서드 안에서

파일 제목이 빈 값이면 예외를 발생시키고 그것을 try-catch로 예외 처리한다.  

 

위와 같은 내용일 경우 메서드 안에서 처리한다.

그리고 이번엔 반대의 예제를 보자!

 

import java.io.*;
public class ExceptionEx16 {
	public static void main(String[] args){
		try {
			File f = createFile(args[0]);
			System.out.println(f.getName() + "파일을 성공적으로 생성");
		} catch (Exception e) {
			System.out.println(e.getMessage() + "다시 입력해주세요.");
		}	
    }
	static File createFile(String fileName) throws Exception {
			if(fileName == null || fileName.equals(""))
				throw new Exception("파일 이름이 유효하지 않음");
			File f = new File(fileName);
			f.createNewFile();
			return f;
	}
}

위 예제는 첫 번째 예제와 달리 예외가 발생한 createFile메서드에서 잘못 입력된 파일 이름을 임의로 처리하지 않고, 호출한 main메서드에게 예외가 발생했음을 알려서 파일이름을 다시 입력받도록 하였다.

 

이처럼 경우에 따라 예외처리를 해주면 된다!!

 

 

*참고서적

Java의 정석

 

 

반응형