티스토리 뷰

프로그래밍/Java

예외처리

안싱미 2016. 1. 25. 10:40

예외처리

예외처리란, 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것.

예외처리의 목적은 예외의 발생으로 인한 실행중인 프로그램의 갑작스런 비정상 종료를 막고, 정상적인 실행상태를 유지할 수 있도록 하는 것.


예시)

userAnswer = console.nextInt();

- userAnswer에 정수 이외의 다른 문자가 입력되면 에러가 발생한다.(자바가 미리 만들어진 예외가 발생된다.)

- 예외가 발생할 때 적절한 처리를 해주지 않으면 프로그램이 종료되어버린다.

- 예외는 상황별로 다른 예외를 발생시킨다.(ex. InputMismatchException, NullPoinerException, ArrayOutOfBoundException예외가 어디에서 발생했는지도 알 수 있다.

- 예외가 ‘던져진다’, 혹은 ‘던저졌다’ 라고 표현한다. throw!!

- 그렇게 던져진 예외는 처리를 반드시 해주어야한다. try ~ catch 라는 키워드를 사용해서!

- 우리가 예외를 직접 만들 수도 있다(실무에서는 예외처리하는 방법을 보고 수준을 평가한다.)


 반드시 외워야하는 예외의 종류

InputMismatchException : 지정한 변수 타입과 다른 타입을 입력받았을 때 발생하는 예외

ArithmeticException : 0으로 나누려할 때 발생하는 예외

NullPointerException : 값이 null인 참조변수의 멤버를 호출하려고 할때 발생하는 예외

ArrayIndexOutOfBoundsException : 배열의 범위를 벗어났을 때 발생하는 예외

NumberFormatException : 문자를 숫자로 변환하려고 할 때 발생하는 예외

FileNotFoundException : 존재하지 않는 파일의 이름을 입력했을 때 발생하는 예외

ClassNotFoundException : 클래스 로딩에 실패했을 때 발생하는 예외



Q. 생판 처음보는 예외는 어떻게하나요?

    첫번째 줄을 복사 → google에 검색!! → stackoverflow !!

 

 

InputMismatchException 

Scanner를 쓸 때 변수 타입과 다른 타입을 입력했을 때 나는 예외.

1. 예외를 처리하지 못했을 때

 

무제-1-01.png

 

2. try~catch로 예외 처리를 했을 때


try 블럭 내에서 예외가 발생한 경우

1. 발생한 예외와 일치하는 catch 블럭이 있는지 확인한다.

2. 일치하는 catch블럭을 찾게 되면, 그 catch블럭 내의 문장들을 수행하고 전체 try-catch문을 빠져나가서 그 다음 문장을 계속해서 수행한다. 만약 일치하는 catch블럭을 찾지 못하면, 예외는 처리되지 못한다.


try 블럭 내에서 예외가 발생하지 않은 경우,

1. catch블럭을 거치지 않고 try-catch 문을 빠져나가서 수행을 계속한다.

무제-1-02.png

3. while문을 써서 제대로 입력할 때 까지 반복되게 처리

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.ktds.smahn;
 
import java.util.InputMismatchException;
import java.util.Scanner;
 
/**
 * 2016.01.25 예외처리
 *
 */
public class InputMissmatchExceptionTest {
 
    public void start() {
 
        System.out.println("정수를 입력하세요! ");
        
        Scanner input = new ScannerSystem.in );
        
        int number = 0;
        
        // 사용자가 정수를 입력할 때까지 반복한다.
        while(true) { 
            
            // 일단 에러가 날지 안날지 모르지만 일단 시도해본다.
            try { 
                
                // 예외가 발생할 가능성이 있는 코드들...
                number = input.nextInt(); 
                //문자를 입력해도 되는거 아닌가?
                //예외가 발생하면 밑에 줄 무시하고 바로 catch로 간다.
                break;
            }
            // try 내부의 코드가 InputMismatchException 을 던진다면,
            // 예외를 받아온다.
            // catch가 실행되는 동안은 프로그램이 종료되지 않는다.
            catch ( InputMismatchException ime ) {
                
                // Scanner의 버그를 해결하기 위한 코드
                input = new ScannerSystem.in ); 
                System.out.println("잘못 입력했습니다. 정수만 입력할 수 있어요.");
                
                // 쓰면 안되는 코드
                // 예외의 구체적인 정보를 알고 싶을 때 쓴다.
                // 구체적인 정보를 알고 난 뒤에는 반드시 지워야 한다.
                //ime.printStackTrace();
                
                // 애용해야하는 코드
                // 어떤 예외가 어떻게 발생했는지 간략히 알려준다.
                System.out.println(
                        ime.getClass().getName() + " 예외가 " + ime.getMessage() + " 때문에 발생했습니다. ");
            }
        }
        
        
        System.out.println("당신이 입력한 정수는 " + number + " 입니다.");
        
    }
 
    public static void main(String[] args) {
        InputMissmatchExceptionTest test = new InputMissmatchExceptionTest();
        test.start();
 
    }
}
 
 
cs

4. swtich문을 이용

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.ktds.smahn;
 
import java.util.InputMismatchException;
import java.util.Scanner;
 
/**
 * 2016.01.25 예외처리
 *
 */
public class InputMissmatchExceptionTest {
 
    public void start() {
 
        System.out.println("정수를 입력하세요! ");
        
        Scanner input = new ScannerSystem.in );
        
        int number1 = 0;
        int number2 = 0;
        int number3 = 0;
        
        int currentStatus = 1
        
        
        while(true) { 
 
            try { 
                
                switch( currentStatus ){
                case 1 :    
                    System.out.println("첫번째 수를 입력하세요.");
                    number1 = input.nextInt(); 
                    currentStatus = 2;
                case 2 : 
                    System.out.println("두번째 수를 입력하세요.");
                    number2 = input.nextInt();             
                    currentStatus = 3;
                case 3 :                     
                    System.out.println("세번째 수를 입력하세요.");
                    number3 = input.nextInt(); 
                    currentStatus = 1;
                }
                
                break;
            }
            // try 내부의 코드가 InputMismatchException 을 던진다면,
            // 예외를 받아온다.
            // catch가 실행되는 동안은 프로그램이 종료되지 않는다.
            catch ( InputMismatchException ime ) {
                
                // Scanner의 버그를 해결하기 위한 코드
                input = new ScannerSystem.in ); 
                System.out.println("잘못 입력했습니다. 정수만 입력할 수 있어요.");
                
                // 쓰면 안되는 코드
                // 예외의 구체적인 정보를 알고 싶을 때 쓴다.
                // 구체적인 정보를 알고 난 뒤에는 반드시 지워야 한다.
                //ime.printStackTrace();
                
                // 애용해야하는 코드
                // 어떤 예외가 어떻게 발생했는지 간략히 알려준다.
                System.out.println(
                        ime.getClass().getName() + " 예외가 " + ime.getMessage() + " 때문에 발생했습니다. ");
            }
        }
        
        
        System.out.println("당신이 입력한 정수는 " + number1 + " 입니다.");
        System.out.println("당신이 입력한 정수는 " + number2 + " 입니다.");
        System.out.println("당신이 입력한 정수는 " + number3 + " 입니다.");
        
    }
 
    public static void main(String[] args) {
        InputMissmatchExceptionTest test = new InputMissmatchExceptionTest();
        test.start();
 
    }
}
 
 
 
cs

 

ArithmeticException 

나누기를 할 때 수를 0으로 나눌려고 할 때 나는 예외

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;
 
import java.util.Scanner;
 
public class ArithmaticExceptionTest {
    
    public void start() {
        Scanner input = new Scanner ( System.in );
        
        int numberOne = 0;
        int numberTwo = 0;
        double result = 0.0;
        
        System.out.println("첫번째 숫자를 입력하세요.");
        numberOne = input.nextInt();
        
        System.out.println("두번째 숫자를 입력하세요.");
        numberTwo = input.nextInt();
        
        try {
            result = numberOne / (double)numberTwo;
        }
        catch ( ArithmeticException ae){
            System.out.println(ae.getMessage());
        }
        
        System.out.println("결과는 " + result + " 입니다." );
        
    }
    
    public static void main(String[] args) {
        ArithmaticExceptionTest test = new ArithmaticExceptionTest();
        test.start();
    }
 
}
 
cs


NumberFormatException

- 문자를 숫자로 바꾸려고 할 때 나는 예외

- 웹에서 정말 많이 씀!!!!

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
46
47
48
49
50
51
 
package com.ktds.smahn;
 
import java.util.Scanner;
 
public class NumberFormatExceptionTest {
 
    /**
     * 문자를 숫자로 바꾸는 메소드
     * @param str
     * @return
     */
    public int parseIntString str ){
        try{
            return Integer.parseInt(str);
        }
        catch(NumberFormatException nfe) {
            return 0;
        }
    }
    
    
    public void start() {
        
        Scanner input = new Scanner ( System.in );
        String numberString = input.next();
        
        // 문자를 정수로 변환한다.
    
        // 문자를 int로 변환한다.
        try{
            int integerNumber = Integer.parseInt( numberString );
            System.out.println(integerNumber);
        }
        catch ( NumberFormatException nfe ) {
            System.out.println(" 숫자 변환에 실패했습니다. ");
            System.out.println(nfe.getMessage());
        }
        
        
    }
    public static void main(String[] args) {
        
        NumberFormatExceptionTest test = new NumberFormatExceptionTest();
        test.start();
        
 
    }
 
}
 
cs  




ArrayIndexOutOfBoundsException 

- 배열의 범위를 벗어났을 때 발생하는 예외

방법 1. 배열 사용하기

ArrayIndexOutOfBoundsException


방법 2. 리스트 사용하기

IndexOutOfBoundsException


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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package com.ktds.smahn;
 
import java.util.ArrayList;
import java.util.List;
 
public class ArrayIndexOutOfBoundExceptionTest {
 
    public void start() { 
        caseOne();
        caseTwo();
    }
    
    public void caseOne() {
        // 배열을 사용함.
        int numbers[] = new int[5];
        
        forint i = 0; i < numbers.length; i++){
            numbers[i] = i;
        }
        
        
        //절대 이렇게 쓰지 않는다..
        try{
            numbers[5= 10;
            
        }
        catch ( ArrayIndexOutOfBoundsException aioobe ){
            System.out.println( aioobe.getMessage() + "번 인덱스는 존재하지 않습니다. ");
        }
        
        /*
         * 결과
         * ==============
         * 0 : 첫번째 인덱스
         * 1 : 두번째 인덱스
         * 2 : 세번째 인덱스
         * 3 : 네번째 인덱스
         * 4 : 다섯번째 인덱스
         */
        
        for(int number : numbers){
            System.out.println(number);
        }
        
    }
    
    public void caseTwo() {
        // 리스트를 사용함
        List<Integer> numbers = new ArrayList<Integer>();
        
        for(int i = 0; i < 5; i++ ){
            numbers.add(i);
        }
        
        for(int i = 0; i < numbers.size(); i++){
            System.out.println(numbers.get(i));
        }
            
        //System.out.println(numbers.get(5)); <- 이렇게 쓰는 대신 위의 for문처럼 쓴다.
        
            /*
             * 결과
             * ==============
             * 0 : 첫번째 인덱스
             * 1 : 두번째 인덱스
             * 2 : 세번째 인덱스
             * 3 : 네번째 인덱스
             * 4 : 다섯번째 인덱스
             */
            
            for(int number : numbers){
                System.out.println(number);
            }            
            
        }
 
    
    public static void main(String[] args) {
        
        ArrayIndexOutOfBoundExceptionTest test = new ArrayIndexOutOfBoundExceptionTest();
        test.start();
    }
 
}
 
 
 
cs
※ 그러나 try~ catch를 써서 예외처리를 절대 절대 하지 말자. 아예 잘못된 부분을 고쳐야 한다. 개발자가 실수하지 않는 한 에러가 나지 않는다.

 


FileNotFoundException 

- 파일이 없는데 참조하고 있을 때 발생하는 예외.

- FileNotFoundException 은 FileInputStream을 적기만해도 빨간줄 --> 예외 여부와 상관없이 반드시 예외처리를 해주어야한다. 

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
 
package com.ktds.smahn;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
 
public class FileNotFoundExceptionTest {
 
    public void start(){
        
        File file = new File("D:\\adsf.ddd");
        try {
            InputStream is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
    public static void main(String[] args) {
        FileNotFoundExceptionTest test = new FileNotFoundExceptionTest();
        test.start();
 
    }
 
}
 
cs

  



NullPointerException 

- 잘못된 널 참조를 할 때 발생하는 에러.(=인스턴스를 만들지 않고 메소드를 사용할 때 발생하는 에러)


NullPointer : 인스턴스화 되지 않은 메모리를

인스턴스화 : 메모리에다가 내 인스턴스를 넣겠다.

인스턴스 : 메모리에 들어있는 데이터

기능(메소드) : 인스턴스화가 되어야만 쓸 수 있다.

 

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
46
47
48
49
50
 
package com.ktds.smahn;
 
public class NullPointerExceptionTest {
 
    public void start(){
        
        String str = null;
        
        forint i = 0; i < 3; i++){
            if( str != null && str.equals("AAA")){
                System.out.println("AAA 입니다.");
            }
            else{
                System.out.println("에러입니다.");
            }
        }
        
    }
    
    
    public static void main(String[] args){
        
        /*
         * primitive type의 기본 값
         * =============================
         * int                 0
         * short               0
         * long                0L
         * byte                0
         * float               0.0F
         * double              0.0 or 0.0D
         * boolean             false
         * char                ''
         * 
         * Reference Type의 기본 값
         * =================================================
         * String                                        null
         * Scanner                                       null
         * System                                        null
         * NullPointerExceptionTest(class name)          null
         * ...                                           null
         * 
         */
        
        NullPointerExceptionTest test = new NullPointerExceptionTest();
        test.start();
    }
}
 
cs

 

마찬가지로 try~ catch를 절대 쓰면 안된다. 대신에 다른 방법을 쓰자. 
방법 1. String str = null; 을 String str = new String("BBB"); 라고 대체하기.

그러나 1번 방법은 좋은 방법이 아니다. 좋은 방법은 방법 2이다.

방법 2. 논리 연산자 사용하기 

 String str = null;

  for( int i = 0; i < 3; i++){
   if( str != null && str.equals("AAA")){
    System.out.println("AAA 입니다.");
   }
   else{
    System.out.println("에러입니다.");
   }
  }


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