예외를 처리하는 방법에는 지금까지 배워 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의 정석
'프로그래밍 > JAVA' 카테고리의 다른 글
[JAVA] 자동 자원 반환 try-with-resources (0) | 2022.11.22 |
---|---|
[JAVA] finally 블럭 (0) | 2022.11.22 |
[JAVA] 예외 발생시키기(throw) (0) | 2022.11.21 |
[ JAVA ] 추상클래스(abstract class)란? (0) | 2022.10.27 |
[ JAVA ] 다형성 - 매개변수의 다형성, 여러 종류의 객체 배열 (0) | 2022.10.27 |