티스토리 뷰

프로그래밍/Java

예외처리(finally)

안싱미 2016. 1. 26. 11:38

finally

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

- 예외가 발생한 경우에는 try --> catch --> finally 순으로,

- 예외가 발생하지 않은 경우에는 try --> finally 순으로 실행된다.

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 com.ktds.smahn;
 
public class FinallyTest {
 
    public void start() {
 
        try {
            int number = Integer.parseInt("123");
 
            System.out.println(number);
        } 
        catch (NumberFormatException nfe) {
            System.out.println("숫자 변환에 실패했습니다.");
        }
        finally {
            //예외 발생 여부에 관계없이 항상 수행되어야하는 문장을 넣는다.
            System.out.println("숫자 변환을 종료합니다.");
            
        }
 
    }
 
    public static void main(String[] args) {
 
        FinallyTest test = new FinallyTest();
        test.start();
 
    }
cs

 

여러개의 에러가 발생했을 경우

아래의 소스는 빨간색 부분에서 NumberFormatException, NullPointerException 예외가 발생하고 있다.

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
32
33
34
35
package com.ktds.smahn;
 
public class FinallyTest {
 
    public void start() {
 
        try {
            int number = Integer.parseInt("abd");
            
            String str = null;
            str.length();
            // 메모리가 없는데 (인스턴스가 아닌데)  인스턴스의 기능을 수행하려고 한다.
 
            System.out.println(number);
        } 
        catch (NumberFormatException nfe) {
            System.out.println("숫자 변환에 실패했습니다." + nfe.getMessage());
        }
        finally {
            //예외 발생 여부에 관계없이 항상 수행되어야하는 문장을 넣는다.
            System.out.println("숫자 변환을 종료합니다.");
            
        }
 
    }
 
    public static void main(String[] args) {
 
        FinallyTest test = new FinallyTest();
        test.start();
 
    }
 
}
 
cs


여러개의 예외가 발생했을 때 처리하는 방법

1. catch문을 여러번 써준다.

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
32
33
34
35
36
37
38
39
40
41
42
43
package com.ktds.smahn;
 
public class FinallyTest {
 
    public void start() {
 
        try {
            int number = Integer.parseInt("123");
            
            String str = null;
            str.length();
            // 메모리가 없는데 (인스턴스가 아닌데)  인스턴스의 기능을 수행하려고 한다.
 
            System.out.println(number);
        } 
        catch (NumberFormatException nfe) {
            System.out.println("숫자 변환에 실패했습니다." + nfe.getMessage());        
        }
        catch(NullPointerException npe){
            System.out.println("잘못된 참조입니다. 객체가 null이 아닌지 확인하세요.");
        }
        finally {
            //예외 발생 여부에 관계없이 항상 수행되어야하는 문장을 넣는다.
            System.out.println("숫자 변환을 종료합니다.");
            
        }
 
    }
 
    public static void main(String[] args) {
 
        FinallyTest test = new FinallyTest();
        test.start();
 
    }
 
}
 
 
 
 
 
 
cs

2. 파이프, instanceof를 써서 해결해준다.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.ktds.smahn;
 
public class FinallyTest {
 
    public void start() {
 
        try {
            int number = Integer.parseInt("123");
            
            String str = null;
            str.length();
            // 메모리가 없는데 (인스턴스가 아닌데)  인스턴스의 기능을 수행하려고 한다.
 
            System.out.println(number);
        } 
        catch (NumberFormatException | NullPointerException nfe) {
            System.out.println("숫자 변환에 실패했습니다." + nfe.getMessage());
            
            if( nfe instanceof NumberFormatException ) { 
                System.out.println("숫자 변환을 할 수 없습니다. ");
            }
            else if( nfe instanceof NullPointerException ) {
                System.out.println("잘못된 참조입니다. ");
            }
        }
 
        finally {
            //예외 발생 여부에 관계없이 항상 수행되어야하는 문장을 넣는다.
            System.out.println("숫자 변환을 종료합니다.");
            
        }
 
    }
 
    public static void main(String[] args) {
 
        FinallyTest test = new FinallyTest();
        test.start();
 
    }
 
}
 
 
 
cs

 


throws를 이용한 예외 처리 책임 전달

- 예외를 처리하는 방법에는 try~ catch문 외에도 예외를 메서드에 선언하는 방법이 있다. 메서드의 선언부에 키워드 throws를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어준다.

void method() throws Exception1, Exception2, ... ExceptionN {

//메서드의 내용

}

- 현재 메소드에서 예외가 발생할 때 예외 처리에 대한 책임을 호출자에게 넘기는 것이다.

- 반드시 호출을 한 애가 try~catch를 써서 잡아야한다.

- 웹 어플리케이션을 만들 때 만약에 제목과 내용을 쓰지 않으면 글 등록이 안된다고 가정할 때, 그 사실을 모른채 내용을 안적고 글쓰기를 누르면, 서버 내부에서는 체크를 한다. 사용자에게 알려준다. 내용 적어야돼~ 그때는 throws쓰면 편리하다.

 



이중 스로우(exception re-throwing)

- 한 메서드에서 발생할 수 있는 예외를 try~catch문을 통해서 메서드 자체적으로 처리하고, 나머지는 선언부에 지정하여 호출한 메서드에서 처리하도록 함으로써 양쪽에서 나누어서 처리할 수 있다.

- 먼저 예외가 발생할 가능성이 있는 메서드에 try~ catch문을 사용해서 예외를 처리해주고 catch문에서 적절한 조치를 취한 후에 throw문을 사용해서 예외를 다시 발생시킨다. 다시 발생한 예외는 이 메서드를 호출한 메서드에게 전달되고 호출한 메서드의 try~catch 문에서 예외를 또다시 처리한다.

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
32
33
34
35
36
37
package com.ktds.smahn;
 
public class ThrowsTest {
    
    public void start(){
        
        MakeExceptions makeExceptions = new MakeExceptions();
        
        int number = 0;
        
        /*
         * parseInt3 실행
         */
        try{
            number = makeExceptions.parseInt3("DEF");
        }
        catch(NumberFormatException nfe){
            System.out.println("변환 실패!!!!!");
            number = 0; 
        }
        
        System.out.println(number);
        
    }
    
    public static void main(String[] args) {
    
        ThrowsTest test = new ThrowsTest();
        test.start();
        
    }
 
}
 
 
 
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
package com.ktds.smahn;
 
public class MakeExceptions {
 
    public int parseInt3( String str ) throws NumberFormatException {
        try {
            return Integer.parseInt(str);
        }
        catch(NumberFormatException nfe){
            System.out.println(str + "은 숫자로 바꿀 수 없습니다.");
            throw nfe;
            
        }
    }
}
 
cs

 


사용자정의 예외 만들기

사용자 정의 예외를 만들기 위해서는 예외 클래스 계층을 이해해야 한다.

* 예외 클래스의 계층

이제까지 익혔던 예외들은 모두 RuntimeException의 종류들이였다.

출처 : Java의 정석

상위의 계층을 보면 RuntimeException은 Exception, Throwable 라는 최상위 클래스에 포함된다.

출처 : Java의 정석

 

Exception을 쓰지 않는 이유 ; 코드가 너무 더러워진다.. --> 반드시 RuntimeException을 extends 한다.

OS를 개발한다면, Exception을 써서 모든 예외를 다 잡는게 맞지만, 웹 환경에서 개발을 할 때는 모든 예외를 잡을 필요가 없다. 잡지 않아도 시스템이 안죽기 때문에...



1. InvalidNumberException이라는 사용자 정의 예외 클래스를 만들고 생성자 오버로딩을 한다.(무조건 외우기)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.ktds.smahn;
 
public class InvalidNumberException extends RuntimeException {
 
    // 생성자 오버로딩
    public InvalidNumberException() {
        super();
    }
    
    public InvalidNumberException( String msg ) {
        super(msg);
    }
    
    public InvalidNumberException( Throwable t ) {
        super(t);
    }
    
    public InvalidNumberException( String msg, Throwable cause ){
        super(msg, cause);
        
    }
 
}
 
cs

 2. 사용자 정의 예외 인스턴스를 생성하고 예외를 던진다. (throws는 쓰지 않아도 된다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.ktds.smahn;
 
public class MakeExceptions {
 
    
    public int parseInt3( String str ) {
        try {
            return Integer.parseInt(str);
        }
        catch(NumberFormatException nfe){
            System.out.println(str + "은 숫자로 바꿀 수 없습니다.");
            
            InvalidNumberException ine = new InvalidNumberException(str + "은 숫자로 바꿀 수 없습니다.");
            throw ine;
            
        }
    }
}
cs


3. 메인 클래스를 실행하면 예외가 발생하지만 try~catch로 잡지 않아도 무방하다.

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 com.ktds.smahn;
 
public class ThrowsTest {
    
    public void start(){
        
        MakeExceptions makeExceptions = new MakeExceptions();
        
        int number = 0;    
        
        /*
         * parseInt3 실행
         */
        number = makeExceptions.parseInt3("DEF");
        
        System.out.println(number);
        
    }
    
    public static void main(String[] args) {
    
        ThrowsTest test = new ThrowsTest();
        test.start();
        
    }
 
}
 
cs

 

 

 

 

 


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함