예외처리 예제

윤재열·2022년 1월 10일
0

Java

목록 보기
17/71

1. 예외처리의 정의와 목적에 대해서 설명하시오.

==============================풀이======================================

  • 정의 : 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것.
  • 목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것.

2. 다음은 실행도중 예외가 발생하여 화면에 출력된 내용이다. 이에 대한 설명 중 옳지 않은 것은?

java.lang.ArithmeticException : / by zero 

at ExceptionEx18.method2(ExceptionEx18.java:12) 

at ExceptionEx18.method1(ExceptionEx18.java:8) 

at ExceptionEx18.main(ExceptionEx18.java:4)

a. 위의 내용으로 예외가 발생했을 당시 호출스택에 존재했던 메서드를 알 수 있다.

b. 예외가 발생한 위치는 method2 메서드이며, ExceptionEx18.java 파일의 12번째 줄이다.

c. 발생한 예외는 ArithmeticException이며, 0으로 나눠어서 예외가 발생했다.

d. method2메서드가 method1메서드를 호출하였고 그 위치는 ExceptionEx18.java파일의 8번째 줄이다.

==============================풀이=====================================

답 :d

  • 해설 : 예외가 발생한 곳은 method2이고 ExceptionEx18.java의 12번째 줄이다. 호출스택은 맨 위에 있는 메서드가 현재 실행 중인 메서드이고 아래 있는 메서드가 바로 위의 메서드를 호출한 것이다. 그래서 main → method1 → method2의 순서로 호출되었음을 알 수 있다.

3. 다음 중 오버라이딩이 잘못 된 것은?

void add(int a, int b)  throws InvalidNumberException, NotANumberException {} 


class NumberException extends Exception {} 

class InvalidNumberException extends NumberException {} 

class NotANumberException extends NumberException {}

a. void add(int a, int b) throws InvalidNumberException, NotANumberException { }

b. void add(int a, int b) throws InvalidNumberException { }

c. void add(int a, int b) throws NotANumberException { }

d. void add(int a, int b) throws Exception { }

e. void add(int a, int b) throws NumberException { }

==============================풀이=====================================

답: d,e

  • 오버라이딩(Overriding)을 할 때, 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
    d를 보면 조상 클래스의 정의된 메서드보다 적은 개수의 예외를 선언한 것처럼 보이지만 Exception은 모든 예외의 최고 조상이므로 가장 많은 개수의 예외를 던질 수 있도록 선언한 것이다.

4.다음과 같은 메서드가 있을때, 예외를 잘못 처리한것은?

void method() throws InvalidNumberException, NotANumberException {} 

class NumberException extends RuntimeException {} 

class InvalidNumberException extends NumberException {} 

class NotANumberException extends NumberException {}

a. try {method( );} catch(Exception e) { }

b. try {method( );} catch(NumberException e) { } catch(Exception e) { }

c. try {method( );} catch(Exception e) { } catch(NumberException e) { }

d. try {method( );} catch(InvalidNumberException e){

} catch(NotANumberException e) { }

e. try {method( );} catch(NumberException e) { }

f. try {method( );} catch(RuntimeException e) { }

==============================풀이=====================================
답 : c

try 블럭 내에서 예외가 발생하면, catch 블럭 중에서 예외를 처리할 수 있는 것을 차례대로 찾아 내려간다. 발생한 예외의 종류와 일치하는 catch 블럭이 있으면 그 블럭의 문장들을 수행하고 try-catch문을 빠져나간다. 일치하는 catch블럭이 없으면 예외는 처리되지 않는다.

발생한 예외의 종류와 일치하는 catch블럭을 찾을 때, instanceof로 검사를 하기 때문에 모든 예외의 최고조상인 Exception이 선언된 catch블럭은 모든 예외를 다 처리할 수 있다. 한 가지 주의할 점은 Exception을 처리하는 catch블럭은 모든 catch블럭 중 제일 마지막에 있어야 한다는 것이다.

Exception을 선언한 catch블럭이 마지막 catch블럭이 아니면 컴파일 에러가 발생한다.

5.아래의 코드가 수행되었을 때 실행결과를 적으시오.

public class Ex5 {
    static void method(boolean b) {
        try {
            System.out.println(1);
            if (b)
                throw new ArithmeticException();
            System.out.println(2);
        } catch (RuntimeException r) {
            System.out.println(3);
            return;
        } catch (Exception e) {
            System.out.println(4);
            return;
        } finally {
            System.out.println(5);
        }
        System.out.println(6);
    }
    public static void main(String[] args) {
        method(true);
        method(false);
    } // main
}

==============================풀이=====================================

method(true)일때,1을출력하고,b가 true일때 ,ArithmeticException을 thorw해줬으니
RuntimeException에서 catch하여 3이 출력한다.후에,reutn이 있으므로 종료시킨다.하지만 finally문이 있으므로 return이 있어도 출력하여 1,3,5가 출력된다.

method(false)일떄, 우선1을 출력하고,false이므로 2가 출력된다.하지만 false에는 아무런 예외가 있지않으므로 내려와서 finally에서 5출력,그리고 6출력하므로 1,2,5,6이 출력된다.

6.아래의 코드가 수행되었을 떄의 실행결과를 적으시오.

public class Ex6 {
    public static void main(String[] args) {
        try {
            method1();
        } catch (Exception e) {
            System.out.println(5);
        }
    }
    static void method1() {
        try {
            method2();
            System.out.println(1);
        } catch (ArithmeticException e) {
            System.out.println(2);
        } finally {
            System.out.println(3);
        }
        System.out.println(4);
    }
    static void method2() {
        throw new NullPointerException();
    }
}

==============================풀이=====================================

우선 main()메서드에서 method1()을 확인해야하니 method1()로가보니 method2()를 알아야한다.따라서 method2()->method1()->main()순으로 해보자.
method2는 throw NullPointerException()이므로 예외를 발생합니다.
method1은 try문의 method2()는 NullPointerException() 런타임의 자식이다.그래서 값은
3,4가 출력이 된다. 이제 main()으로 가면 여기서 finally에서3이 출력되었고,4가 Exception에 잡혔기 때문에 5로 출련된다 따라서 3,5가 출력된다.

7.아래의 코드가 수행되었을 때의 실행결과를 적으시오.

public class Ex7 {
        static void method(boolean b) {
            try {
                System.out.println(1);
                if (b)
                    System.exit(0);
                System.out.println(2);
            } catch (RuntimeException r) {
                System.out.println(3);
                return;
            } catch (Exception e) {
                System.out.println(4);
                return;
            } finally {
                System.out.println(5);
            }
            System.out.println(6);
        }
        public static void main(String[] args) {
            method(true);
            method(false);
        } // main
    }

==============================풀이=====================================

method(true) : 우선 1이 출력된다, 만약 b값이 true면...?System.exit(0)..?
이것은 프로그램이 즉시 종료된다.이럴때는 finally블럭조차도 수행되지 않는다.
만약 메인메서드에서 method(false),method(true)순으로 한다면 false는 출력되고 true에서 1이 출력된다.

8. 다음은 1~100사이의 숫자를 맞추는 게임을 실행하던 도중에 숫자가 아닌 영문자를 넣어서 발생한 예외이다. 예외처리를 해서 숫자가 아닌 값을 입력했을 때는 다시 입력을 받도록 보완하라.

ps.정말 좋은 문제인것같다 Math.random(),Scanner(),do-while문,예외처리까지 다들어가있다.

1100사이의 값을 입력하세요 :50 

더 작은 수를 입력하세요. 

1100사이의 값을 입력하세요 :asdf 

Exception in thread "main" java.util.InputMismatchException 

at java.util.Scanner.throwFor(Scanner.java:819) 

at java.util.Scanner.next(Scanner.java:1431) 

at java.util.Scanner.nextInt(Scanner.java:2040) 

at java.util.Scanner.nextInt(Scanner.java:2000) 

at Exercise8_8.main(Exercise8_8.java:16)
public static void main(String[] args) {
		// 1~100 사이의 임의의 값을 얻어서 answer에 저장한다.
		int answer = (int) (Math.random() * 100) + 1;
		int input = 0; // 사용자입력을 저장할 공간
		int count = 0; // 시도횟수를 세기 위한 변수

		do {
			count++;
			System.out.print("1과 100사이의 값을 입력하세요 :");
			input = new Scanner(System.in).nextInt();
            
			if (answer > input) {
				System.out.println("더 큰 수를 입력하세요 .");
			} else if (answer < input) {
				System.out.println("더 작은 수를 입력하세요 .");
			} else {
				System.out.println("맞췄습니다 .");
				System.out.println("시도횟수는 " + count + "번입니다 .");
				break; // do-while문을 벗어난다
			}
		} while (true); 
	} 
}

==============================풀이=====================================

package JavaStandard8.Ex;
import java.util.Scanner;

public class Ex8 {
    public static void main(String[] args) {

        // 1~100 사이의 임의의 값을 얻어서 answer에 저장한다.
        int answer = (int) (Math.random() * 100) + 1;   //1부터 100까지의 난수
        int input = 0; // 사용자입력을 저장할 공간
        int count = 0; // 시도횟수를 세기 위한 변수
        do {
            count++;
            System.out.print("1과 100사이의 값을 입력하세요 :");
           try {
               input = new Scanner(System.in).nextInt();   //<예외처리
           }catch(InputMismatchException e){
               System.out.println("유효하지 않은 값입니다. 다시 값을 입력해주세요.");
              continue; //반복문제어 continue를 만나면 해당 반복문 탈출하고 다 반복문을 실행한다.
           }
            if (answer > input) {
                System.out.println("더 큰 수를 입력하세요 .");
            } else if (answer < input) {
                System.out.println("더 작은 수를 입력하세요 .");
            } else {
                System.out.println("맞췄습니다 .");
                System.out.println("시도횟수는 " + count + "번입니다 .");
                break; // do-while문을 벗어난다
            }
        } while (true);
    }
}

9.다음과 같은 조건의 예외클래스를 작성하고 테스트하시오.

클래스명 : UnsupportedFuctionException

  • 조상클래스명 : RuntimeException
  • 멤버변수 :
    이름 : ERR_CODE
    저장값 : 에러코드
    타입 : int
    기본값 : 100
    제어자 : final private
  • 메서드 :
  1. 메서드명 : getErrorCode
    기능 : 에러코드(ERR_CODE)를 반환한다.
    반환타입 : int
    매개변수 : 없음
    제어자 : public
  2. 메서드명 : getMessage
    기능 : 메세지의 내용을 반환한다. (Exception클래스의 getMessage( )를 오버라이딩)
    반환타입 : String
    매개변수 : 없음
    제어자 : public
class Exercise8_9 {
	public static void main(String[] args) throws Exception {
		throw new UnsupportedFuctionException("지원하지 않는 기능입니다.", 100);
	}
}
[실행결과]

Exception in thread "main" UnsupportedFuctionException: [100] 지원하지 않는 기능입니다. 

at Exercise8_9.main(Exercise8_9.java:5)

==============================풀이=====================================

package JavaStandard8.Ex;

public class UnsupportedFuctionException extends RuntimeException{
  private final int ERR_CODE =100;

    UnsupportedFuctionException(String msg, int errCode) { // 생성자
       super(msg);    //조상의 생성자 RuntimeException(String msg)를 호출
       
  }

    public UnsupportedFuctionException(String msg) {
        this("msg",100);//ERR_CODE를 100으로 초기화한다.
        
    }

    public int getErrorCdoe(){
      return ERR_CODE;  //에러코드를 반환한다.
  }

    @Override
    public String getMessage() {    //Exception의 getMessage()를 오버라이딩한다.
        return getErrorCdoe()+super.getMessage();
    }
}

==============================풀이=====================================

에러메시지를 저장하는 인스턴스변수 msg는 상속받은 것이므로 조상의 생성자를 호출해서 초기화되도록 해야 한다. ERR_CODE는 한 번 값이 지정되면 바뀌는 값이 아니라서 final을 붙여서 상수로 했다. 그리고 생성자를 통해 초기화하였다.
getMessage() 역시 조상으로부터 상속받은 것이며, ERR_CODE도 같이 출력되도록 하기 위해 오버라이딩했다. 조상의 메서드를 오버라이딩할 때는, 가능하다면 조상의 메서드를 재활용하는 것이 좋다.

10.아래의 코드가 수행되었을 때의 실행결과를 적으시오.

public class Ex10 {
   
        public static void main(String[] args) {
            try {
                method1();
                System.out.println(6);
            } catch (Exception e) {
                System.out.println(7);
            }
        }
        static void method1() throws Exception {
            try {
                method2();
                System.out.println(1);
            } catch (NullPointerException e) {
                System.out.println(2);
                throw e;
            } catch (Exception e) {
                System.out.println(3);
            } finally {
                System.out.println(4);
            }
            System.out.println(5);
        }
        static void method2() {
            throw new NullPointerException();
        }
    }
    

==============================풀이=====================================

public class Ex10 {

        public static void main(String[] args) {
            try {
                method1();
                System.out.println(6);
            } catch (Exception e) {
                System.out.println(7);
            }
        }
        static void method1() throws Exception {
            try {
                method2();
                System.out.println(1);
            } catch (NullPointerException e) {
                System.out.println(2);
                throw e;
            } catch (Exception e) {
                System.out.println(3);
            } finally {
                System.out.println(4);
            }
            System.out.println(5);
        }
        static void method2() {
            throw new NullPointerException();   //NullPointerException는 RunTimeException을 상속받고있다.
        }
    }

아까와 마찬가지로 method2()->method1()->main()순으로 보자.
method2()가 실행되면 NullPointExceoption()

profile
블로그 이전합니다! https://jyyoun1022.tistory.com/

0개의 댓글