본문 바로가기
생활코딩/JAVA

생활코딩 - JAVA (예외 던지기)

by Love of fate 2020. 12. 30.
728x90
반응형

[예외던지기]

문제를 다른 사람에게 던질 수도 있고 자기 자신이 처리할 수도 있다.

 

*[F1]키를 누르고 [javadoc for 'java.io.FileReader.FileReader(String)'] 같은 생성자에 관한 도움말을 누르면 FileReader의 생성자에 대한 자바 API를 확인할 수 있다.

해당 도움말에서 중요한 것은 Throws 부분이다. Throws는 FileReader 생성자를 사용하는 쪽에서 반드시 FileNOtFoundException에 대한 예외 처리를 강제한다는 의미이다.

 

[예외 사슬]

1
2
3
4
try {
    new FileReader("out.txt");
}catch(){
}

FileReader라는 API의 사용자에게 던진 예외를 처리하기 위해 catch를 한 것이다. API는 throws한 것이고 그 던진 것을 catch한 것이다. API가 예외를 throws했다면 그것을 잡을 수도 있겠지만 그 폭탄을 다른 사람에게 던질 수도 있다는 뜻이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package org.opentutorials.javatutorials.exception;
import java.io.*;
class B{
    void run(){
        BufferedReader bReader = null;
        String input = null;
        try {
            bReader = new BufferedReader(new FileReader("out.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try{
            input = bReader.readLine();
        } catch (IOException e){
            e.printStackTrace();
        }       
        System.out.println(input); 
    }
}
class C{
    void run(){
        B b = new B();
        b.run();
    }
}
public class ThrowExceptionDemo {
    public static void main(String[] args) {
         C c = new C();
         c.run();
    }   
}

위의 코드는 B.run이 FileReader의 생성자와 BufferedReader.readLine가 던진 예외를 try...catch로 처리한다. 즉 B.run이 예외에 대한 책임을 지고 있다.

그런데 B.run이 예외 처리를 직접 하지 않고 다음 사용자 C.run에게 넘길 수 있다. 아래의 코드를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.opentutorials.javatutorials.exception;
import java.io.*;
class B{
    void run() throws IOException, FileNotFoundException{
        BufferedReader bReader = null;
        String input = null;
        bReader = new BufferedReader(new FileReader("out.txt"));
        input = bReader.readLine();
        System.out.println(input); 
    }
}
class C{
    void run(){
        B b = new B();
        b.run();
    }
}
public class ThrowExceptionDemo {
    public static void main(String[] args) {
         C c = new C();
         c.run();
    }   
}

B 내부의 try...catch 구문은 제거되었고 run 옆에 throws IOException, FileNotFoundException이 추가되었다. 이것은 B.run 내부에서 IOException, FileNotFoundException에 해당하는 예외가 발생하면 이에 대한 처리를 B.run의 사용자에게 위임하는 것이다. 위의 코드에서 B.run의 사용자는 C.run이다. 따라서 C.run은 아래와 같이 수정돼야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package org.opentutorials.javatutorials.exception;
import java.io.*;
class B{
    void run() throws IOException, FileNotFoundException{
        BufferedReader bReader = null;
        String input = null;
        bReader = new BufferedReader(new FileReader("out.txt"));
        input = bReader.readLine();
        System.out.println(input);
    }
}
class C{
    void run(){
        B b = new B();
        try {
            b.run();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class ThrowExceptionDemo {
    public static void main(String[] args) {
         C c = new C();
         c.run();
    }   
}

차이점은 아래와 같다.

 

예외 처리는 귀찮은 일이다. 그래서 예외를 다음 사용자에게 전가(throw)하거나 try...catch로 감싸고 아무것도 하지 않고 싶은 유혹에 빠지기 쉽다. 하지만 예외는 API를 사용하면서 발생할 수 있는 잠재적 위협에 대한 API 개발자의 강력한 암시다. 이 암시를 무시해서는 안 된다.

728x90
반응형