본문 바로가기
솔루션모음/자바 기초부터 하나씩

[자바 기초부터 하나씩/12장 연습문제 솔루션 답지 해답] 래퍼클래스와 예외클래스

by 이얏호이야호 2020. 4. 1.

1. 참 또는 거짓

만약 거짓이면, 이유를 설명하여라.

a. 원시 유형 변수는 반드시 객체가 되어야 한다.

: 거짓. 원시 유형변수는 객체 참조인 유일한 변수입니다.

b. Integer x;는 컴파일오류(compile time error)를 발생시킨다.

: 거짓. 컴파일 오류가 나지 않습니다.

c. Integer y = new Integer();는 컴파일 오류를 발생시킨다.

:

d. Integer z = new Integer(3);는 컴파일 오류를 발생시킨다.

: 거짓. 제대로 된 Integer 3이 들어가므로 오류가 나지 않습니다.

e. Integer u = new Integer(3.14);는 컴파일 오류를 발생시킨다.

:

f. Integer v = new Integer("3.2");는 컴파일 오류를 발생시킨다.

:

g. Integer w = new Integer("345");는 컴파일 오류를 발생시킨다.

: 거짓. 값이 345인 정수 작성이 가능합니다. 오류가 없습니다.

h. 예외는 실행 오류(runtime error)와 같다.

:

I. 영으로 나누는 것은 ArithmeticException을 전달하게(throw) 만든다.

:

j. 범위를 벗어난 배열 인덱스는 예외를 유발시킨다.

:

k. 너무 많이 중첩된 루프는 예외의 예이다.

: 거짓. 필요한 만큼 루프를 중첩할 수 있습니다.

l. 예외는 객체이다.

:

m. 모든 try 블록은 finally블록과 함께 사용되어야 한다.

: 거짓. finally블록이 반드시 필요하진 않습니다. 없어도 실행 가능합니다.

n. 사용자 자신의 예외 클래스를 정의할 수 없다.

: 거짓.

o. try 블록마다 정확히 하나의 catch 블록이 허용된다.

: 거짓. catch블록은 여러 개의 클래스를 extends할 수 있습니다.

 

 

3. 컴파일러실행

다음의 클래스를 생각해보자.

public class LinearSearch

{ public static int search(Object[] x, Object key, int size)

{

for(int I=0;i<size;i++)

if(x[i].equals(key))

return i;

return -1;

}

}

다음 중 어느 명령어 한 쌍이 컴파일 되겠는가? 설명하여라.

a. Int[] numbers = {22, 55, 33, 66};

int place = LinearSearch.search(numbers, 55, numbers.length);

: 컴파일 되지 않습니다. Int[] number가 아닌 int[] numbers를 사용해야 컴파일이 가능합니다.

b. int[] numbers = {22, 55, 33, 66};

int place = LinearSearch.search(numbers, 55, numbers.length);

: 컴파일 되지 않습니다. 객체 배열이 필요한 메소드에 배열을 전달하는 것이 올바르지 않기 때문입니다.

c. Integer[] numbers = {22, 55, 33, 66};

int place = LinearSearch.search(numbers, 55, numbers.length);

: 컴파일 됩니다.

 

 

5. 출력 계산

32-비트 정수의 곱은 64-비트가 된다. 만약 곱의 결과 64비트 중에서 상위 32개 비트가 영이면, 결과 값은 간단히 하위 32개 비트가 된다. 그러나 만약 결과의 상위 32개 비트가 영이 아니면, 32-비트 정수를 다루고 있으므로 오버플로우(overflow)가 발생하지만, 이때 자바는 ArithmeticException을 전달하지(throw) 않고, 대신에 곱셈 결과의 32개 하위 비트를 반환한다. 실제로 정수에 대한 곱셈 연산자의 *의 계산에서는 결코 실행 예외(runtime exception)가 전달되지 않는다.

a. 다음 프로그램의 출력은 무엇인가?

public class Testint

{ public static void main(String[] args)

{

Integer x = 2;

for(int i=0;i<10;i++)

{

x=x*x;

System.out.println(x.equals(0));

}

}

}

출력

false

false

false

false

true

true

true

true

true

true

b. 만약 Integer x = 2;int x = 2;로 대체되면 어떤 일이 발생하겠는가?

: equals메소드를 썼기 때문에 컴파일이 되지 않습니다.

 

 

 

 

 

7. 출력 계산

다음 프로그램의 출력을 결정하여라.(코드는 빌 베너스(Bill Venners)1997 자바월드(JavaWorld 기사에서 인용하였다).

public class Ball extends Exception{}

 

public class Pitcher

{ private static Ball ball = new Ball();

static void playBall()

{

int i =0;

while(true)

{ try

{ if(i%4==3)

{

throw ball;

}

++i;

}

catch (Ball b)

{

i=0;

System.out.println("Reset");

}

}

}

public static void main(String[] args)

{

Pitcher.playBall();

}

}

출력

Reset

Reset

Reset

Reset

Reset

......

Reset이 무한출력됩니다.

 

8. try-catch-finally의 기본 구문과 의미

다음 코드 구조를 생각해 보고 이어지는 질문에 답하여라.

try

{...코드 0...}

catch(Exception1 e1)

{...코드 1...}

catch(Exception2 e2)

{...코드 2...}

finally

{...코드 3...}

코드4...

a. 만약 어떤 예외도 전달되지 않으면(throw)않으면, 어느행(코드0,코드1,코드2,코드3,코드4)이 실행되는가?

: 코드0, 코드3, 코드4가 실행될것입니다.

b. 만약 Exception1 유형의 예외가 코드0에서 전달되면, 어느 행(코드0,코드1,코드2,코드3,코드4)이 실행되는가?

: 코드0, 코드1, 코드3, 코드4가 실행될 것입니다.

c.만약 Exception2 유형의 예외가 코드0에서 전달되면, 어느 행(코드0,코드1,코드2,코드3,코드4)이 실행되는가?

: 코드0 , 코드2, 코드3, 코드4가 실행될 것입니다.

d. 만약 Exception1이나 Exception2 어디에도 속하지 않는 예외가 코드0에서 전달되면, 어느 행(코드0,코드1,코드2,코드3,코드4)이 실행되는가?

: 코드0과 코드3이 실행될 것입니다.

 

 

 

 

10. 예외 처리에 대한 지침

Sourceforge.net에서는 예이를 전달하고 잡아내는 데에 대한 지침을 공지하였다. 다음은 sourceforge.net의 몇 가지 예와 설명이다. 각각의 를 다음에 적은 설명중 적당한 것과 연결하여라.

a. public void methodThrowingException() throws Exception {}

b.

public class Foo {

public void bar()

{

try

{

//작업 실행

}

catch(Throwable th)

{

 

}

}

}

c.

 

public class Foo {

public void bar()

{

try

{

try

{

 

}catch(Exception e){

throw new WrapperException(e);

}

}

catch(WrapperException e)

{

//좀 더 많은 작업 실행

}

}

}

d.

 

public class Foo {

public void bar() throws Exception

{

try

{

//작업 실행

}

catch(NullPointerException npe)

{

}

}

}

f.

public class Foo

{

public void bar()

{

throw new NullPointerException();

}

}

 

g.

 

public class Foo {

public void bar()

{

try

{

//작업실행

}

catch(SomeException se)

{

throw se;

}

}

}

설명 :

1. NullPointerException을 잡아내지 마라. NullPointerException 은 코드에서 심각한 버그가 존재한다는 것을 알려주는 것이다. catch 블록은 다른 더욱 포착하기 힘든 오류를 발생시켜 원래의 오류를 모호하게 만들 수 있다.

; d

2. 예외를 전달하는 메소드 헤더의 사용을 피해라. 애매한 인터페이스를 문서화하거나 이해하는 것은 어려운 일일 수 있다. RuntimeException이나 확인 예외로부터 파생된 클래스를 사용하여라.

: a

3. Throwable 예외를 잡는 것을 피해라. 이는 OutOfMemoryError와 같은 예외를 잡아내는 것처럼 범위가 너무 넓다.

: b

4. 예외 잡는 것을 흐름 제어(flow control)로 사용하지 마라. 흐름 제어로서 예외를 사용하는 것은 GOTO와 같은 코드를 만들게 되고, 디버깅 시에 실제 예외들을 알기 어렵게 만든다.

: c

5. 잡아낸 예외를 다시 전달하지 마라. 잡은 예외를 다시 전달하는 catch블록은 코드의 크기와 실행의 복잡성만 증가시킨다. 예외를 잡아내고 새로운 예외를 다시 전달하는 것이 적합한 때는 따로 있다.

: g

6. ‘ 원래의예외 유형을 전달하려고 하지 마라. 원래 그대로의 RuntimeException, Throwable, Exception, Error를 전달하기 보다는 서브 클래스 예외나 오류를 사용하여라.

: e

7. NullPoineterException을 전달하는 것을 피해라. 사람들은 이 예외를 JVM이 전달했다고 생각할 것이다. 대신에 IllegalArgumentException을 사용하는 것을 고려해 보아라. 이렇게 하는 것이 명확하게 프로그래머가 발생시킨 예외로 보일 것이다.

: f

 

 

 

 

댓글