서노썬
sun noes sun
서노썬
전체 방문자
오늘
어제
  • 카테고리 (142)
    • Java (89)
      • Day1 (20)
      • Day2 (16)
      • Day3 (4)
      • Day4 (5)
      • Day5 (2)
      • Day6 (2)
      • Day7 (4)
      • Day8 (6)
      • Day9 (3)
      • Day10 (0)
      • Day11 (0)
      • Day12 (0)
      • Day13 (3)
      • Day14 (0)
      • Day15 (0)
      • Day16 (0)
      • Day19 (0)
      • Day20 (0)
      • Day21 (2)
      • Day22 (4)
      • Day23 (2)
      • Day24 (5)
      • Day25 (4)
      • Day27 (2)
      • Day28 (3)
      • Day29 (1)
      • Day30 (1)
      • Day31 (0)
      • Day32 (0)
      • Dat33 (0)
      • Day34 (0)
      • Day35 (0)
      • Day36 (0)
    • HTML (37)
      • Day36 (20)
      • Day37 (3)
      • Day38 (2)
      • Day39 (8)
      • Day40 (3)
    • SQL (4)
      • Day40 (4)
      • Day41 (0)
      • Day42 (0)
      • Day43 (0)
      • Day44 (0)
      • Day45 (0)
    • JSP (0)
      • Day46 (0)
      • Day75 (0)
    • PYTHON (0)
      • Day75 (0)
      • Day76 (0)
    • Photo (12)

블로그 메뉴

  • 홈
  • 방명록

인기 글

최근 글

태그

  • 자바break
  • java메뉴입력
  • java데이터타입
  • java자료형
  • 자바continue
  • 논리연산자
  • 자바연산자
  • 자바자료형
  • 자바
  • Java

티스토리

hELLO · Designed By 정상우.
서노썬

sun noes sun

Java/Day23

[Java] 자바의 정석 Chapter8. 예외처리(Exception Handling) - 연습문제

2021. 12. 5. 11:51

[ 자바의 정석 Chapter8. 예외처리(Exception Handling) - 연습문제 ]

 

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

 

(1) 예외처리의 정의

- 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 대비한 코드를 작성하는 것

 

(2) 예외처리의 목적

- 예외 상황이 발생했을 때 프로그램을 종료하지 않고 정상 실행 상태가 유지될 수 있도록 하기 위해

 

 

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

java.lang.ArithmeticException : / by zero
	at ExceprionEx18. method2(ExceptionEx18.java : 12)
	at ExceprionEx18. method1(ExceptionEx18.java : 8)
	at ExceprionEx18. main(ExceptionEx18.java : 4)

a. 위의 내용으로 예외가 발생했을 당시 호출스택에 존재했던 메서드를 알 수 있다.
b. 예외가 발생한 위치는 method2 메소드이며, ExceptionEx18.java 파일의 12번째 줄이다.
c. 발생한 예외는 ArithmeticException이며, 0으로 나누어서 예외가 발생했다.
d. method2메소드가 method1메소드를 호출하였고 그 위치는 ExceptionEx18.java파일의 8번째 줄이다.

 

☞ 예외의 종류는 java.lang.ArithmeticException에서 알 수 있듯이 'ArithmeticException' 산술연산의 예외가 발생했다. 예외의 원인은 / by zero에서 알 수 있듯이 0으로 나눗셈을 했기 때문이다. 

 

at ExceprionEx18. method2(ExceptionEx18.java : 12)
at ExceprionEx18. method1(ExceptionEx18.java : 8)
at ExceprionEx18. main(ExceptionEx18.java : 4)

 

으로 확인해볼 수 있는데, 제일 아래 main 메소드에서 method1 메소드를 호출하였고, method1 메소드에서 method2를 호출했는데, method2의 이 때 ExceptionEx18.java 파일의12번째 줄에서 예외가 발생했다.

 

 

8-3. 다음 중 오버라이딩이 잘못된 것은? (모두 고르시오)

void add(int a, int b)
	throw 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{}

 

☞ 오버라이딩 정의

- 부모 클래스에게 상속받은 메소드를 자식 클래스에서 재정의하는 것

 

☞ 오버라이딩 방법

- 부모 클래스와 시그니처(리턴 타입, 메소드 이름, 매개 변수 목록)가 동일해야 한다.

- 상속받은 메소드의 접근 제어자보다 더 넓은 범위로 접근 제어자를 선언할 수 없다.

- 새로운 예외를 throws 할 수 없다.

 

☞ void add(int a, intb) throw InvalidNumberException, NotANumberException{} 에서는 예외에 대해 InvalidNumberException과  NotANumberException 으로 던짐을 명시하고 있다. 그런데, NumberException은 이 둘이 상속받은 부모 클래스이고, 그 위로 Exception 클래스가 존재하고 있다. 그런데 오버라이딩은 하위 클래스에서 상위 클래스보다 더 많은 수의 예외를 선언할 수 없기 때문에 더 넓은 범위로 던짐을 명시할 수 없기 때문에 Exception과 NumberException으로 던짐을 명시하여 오버라이딩 할 수 없다.

 

 

8-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) {}

 

☞  catch(Exception e)는 최상위 예외처리 블럭이기 때문에 제일 마지막에 위치해야 한다.

 

 

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

class Exercise8_5
{
	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);
	}
}

 

☞

1

3

5

1

2

5

6

 

☞  if(b) throw new ArithmeticException(); 에서 if 값이 true일 때 ArithmeticException으로 던져지고, ArithmeticException은 RuntimeException의 자손이므로 catch(RuntimeException e)에서 처리가 된다. 때문에 3이 출력되고 return을 만나 식을 빠져나가게 되는데, 이 때 fianlly는 실행이 되기 때문에 5가 출력된다.

 

☞ if(b) throw new ArithmeticException(); 에서 if 값이 false일 때 ArithmeticException으로 던져지지 않기 때문에 아래의 2가 출력된다. 그리고 처리해야 할 예외 상황이 없기 때문에 fianlly가 실행되어 5가 출력되고, 식을 빠져나간 후 6이 출력된다.

 

 

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

class Exercise8_6
{
	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.prinltn(2);
		}
		finally
		{
			System.out.println(3);
		}
	}

	static method2()
	{
		throw new NullPointerException();
	}
}

 

☞ NullPointerException : 인스턴스(객체)가 제대로 생성되지 않았을 때의 예외 상황

 

☞ 

3

5

 

☞ 메인 메소드에서 method1을 호출했고, method1에서 method2를 호출했다. method2에서 NullPointerException이 발생했는데 method2에는 이 예외를 처리해줄 try~catch 블럭이 없기 때문에 method2는 종료되고 method1으로 돌아가게 된다. 그런데 method1에도 NullPointerException을 처리할 try~catch 블럭이 없기 때문에 method1은 종료되고, finally가 실행되어 3이 출력된다. method1까지 종료되어 메인 메소드로 돌아가게 되고 메인 메소드에는 NullPointerException에 대한 처리가 가능한 Exception이 존재하기 때문에 5가 출력된다.

 

 

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

class Exercise8_7
{
	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);
	}
}

 

☞

1

 

☞ 메인 메소드에서 method를 true의 값으로 호출했고, try 블럭에 들어가 1이 출력된다. 그리고 if(b) System.exit(0); 를 만나고 if의 값은 true이기 때문에 System.exit(0);가 실행되는데 System.exit(0);을 만나게 될 경우 프로그램이 강제로 종료된다. 때문에 finally도 실행되지 않고 바로 종료가 된다.

 

 

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

1과 100사이의 값을 입력하세요 : 50
더 작은 수를 입력하세요.
1과 100사이의 값을 입력하세요 :  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 Exercuse8_8.main(Exercise8_8..java :16)
import java.util.*;

class Exercise8_8
{
	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;
			}
		}
		while(true);
	}
}
- 실행결과
1과 100사이의 값을 입력하세요 :50
더 작은 수를 입력하세요.
1과 100사이의 값을 입력하세요 :asdf
유효하지 않은 값입니다. 다시 값을 입력해주세요.
1과 100사이의 값을 입력하세요 :25
더 큰 수를 입력하세요.
1과 100사이의 값을 입력하세요 :38
더큰 수를 입력하세요.
1과 100사이의 값을 입력하세요 :44
맞췄습니다.
시도횟수는 5번입니다.

 

☞

import java.util.*;

class Exercise8_8
{
	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사이의 값을 입력하세요 :");

			try
			{
				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 + "번입니다.");
				}
			}
			catch(InputMismatchException ie)
			{
				System.out.println("유효하지 않은 값입니다. 다시 입력하세요.");
				continue;
			}
			while(true);
		}
	}
}

 

☞ do~while문 안에 try~catch 블럭을 넣어서 발생하게 될 예외상황에 대한 처리를 해준다. 이 때 입력한 수가 데이터 형과 맞지 않을 때 예외를 처리해주는 'InputMismatchException' 을 사용한다. 유효하지 않은 값에 대한 출력문을 실행하고 continue를 만나 다시 돌아가게 한다.

 

 

8-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)

 

☞

import java.util.*;

class UnsupportedFuctionException extends RuntimeException
{
	private final int ERR_CODE;

	UnsupportedFuctionException(Stirng message)
	{
		this(message, 100);
	}
	
	UnsupportedFuctionException(String message, int errCode)
	{
		super(message);
		this.ERR_CODE = errCode;
	}
	public int getErrorCode()
	{
		return ERR_CODE;
	}
	public String getMessage()
	{
		return "[" + getErrCode() : "]" + super.getMessage();
	}
}

class Exercise8_9
{
	public static void main(String[] args) throws Exception
	{
		throw new UnsupportedFuctionException("지원하지 않는 기능입니다." , 100);
	}
}

 

 

 

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

class Exercise8_10
{
	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();
	}
}

 

☞

2

4

7

 

☞ 메인 메소드에서 method1을 호출했고, method1에서 method2를 호출했다. method2에서 NullPointerException을 처리할 try~catch 블럭이 없기 때문에 method2는 종료되고 method1으로 돌아가게 된다. method1에는 NullPointerException을 처리할 블럭이 있기 때문에 2가 출력되고 throw e에 의해 e가 다시 던져졌지만 method1에는 이를 처리할 try~catch문이 더 이상 존재하지 않기 때문에 메인 메소드로 예외가 던져진다. 이 때 fianlly가 실행되어 4가 출력된다. 메인 메소드에는 던져진 예외를 처리할 try~catch 블럭이 존재하기 때문에 7이 출력되고 식이 종료된다.

'Java > Day23' 카테고리의 다른 글

[Java] 자바의 정석 Chapter7. 객체지향 프로그래밍2 - 연습문제  (0) 2021.11.29
    'Java/Day23' 카테고리의 다른 글
    • [Java] 자바의 정석 Chapter7. 객체지향 프로그래밍2 - 연습문제

    티스토리툴바