자바프로그래밍 언어: 패키지 및 예외<2>

 

11. finally의 필요성

예외가 발생하든 발행하지 않든 무조건 수행하는 부분이 바로 finally영역이다. 이것은 뒤에서 Database처리나 File처리를 한다면 꼭 필요한 부분이다. 이유는 Database를 열었다거나 또는 File을 열었다면 꼭 닫아주고 프로그램이 종료되어야 하기 때문이다.
다음은 구성이다.
try{
// 예외가 발생 가능한 문장들;
} catch(예상되는_예외객체1 변수명){
// 해당 예외가 발생했을 시 수행할 문장들;
} finally{
// 예외발생 여부와 상관없이 수행할 문장들;
}

FinallEx1.java

01  import static java.lang.System.out;
02  class FinallyEx1 {
03
04	public static void main(String[] args) {
05		int[] var = {10,200,30};
06		for(int i=0 ; i <= 3 ; i++) {
07			try{
08				out.println((i+1)+"번째");
09				out.println("var["+i+"] : "+var[i]);
10				out.println("~~~~~~~~~~~~~");
11			}catch(ArrayIndexOutOfBoundsException ae){
12				out.println("배열을 넘었습니다.");
13				return;
14			}finally{
15				out.println(":::::: Finally ::::::");
16			}
17		}//for의 끝
18
19		out.println("프로그램 끝!");
20	}
21  }

실행결과

1번째

var[0] : 10

~~~~~~~~~~~~~~~~~~~

:::::: Finally ::::::

2번째

var[1] : 200

~~~~~~~~~~~~~~~~~~~

:::::: Finally ::::::

3번째

var[2] : 30

~~~~~~~~~~~~~~~~~~~

:::::: Finally ::::::

4번째

배열을 넘었습니다.

:::::: Finally ::::::

프로그램 끝!

:: 이렇게 해서 finally영역은 예외가 발생하든 하지 않든 무조건 수행함을 알아 보았다.

 

 

12. 사용자 정의 예외

사용자 정의 Exception이 필요한 이유는 표준예외가 발생할 때 예외에 대한 정보를 변경하거나 정보를 수정하고자 한다면 사용자가 직접 작성하여 보안된 예외를 발생시켜 원하는 결과를 얻는데 있다.

사용자 정의 Exception을 작성하기 위해서는 Throwable을 받지 않고 그 하위에 있으면서 보다 많은 기능들로 확장되어 있는 Exception으로부터 상속을 받는 것이 유용하다. 물론 입/출력에 관련된 예외를 작성하기 위해 IOException으로부터 상속을 받는 것이 보편적인 것이다.

UserException.java

01  public class UserException extends Exception{
02
03	private int port = 772;
04	public UserException(String msg){
05		super(msg);
06	}
07	public UserException(String msg, int port){
08		super(msg);
09		this.port = port;
10	}
11	public int getPort(){
12		return port;
13	}
14  }

UserExceptionTest.java

01  class UserExceptionTest {
02
03	public void test1(String[] n) throws UserException{
04	    System.out.println("Test1");
05	    if(n.length < 1)
06	        throw new UserException("아무것도 없다네"); // 강제 예외 발생
07	    else
08	        throw new UserException("최종 예선",703); // 강제 예외 발생
09	}
10	public static void main(String[] args) {
11	    UserExceptionTest ut = new UserExceptionTest();
12	    try{
13	        ut.test1(args);
14	    }catch(UserException ue){
15 	//     System.out.println(ue.getMessage());
16	        ue.printStackTrace();
17	    }
18
19	}
20  }

 

13. 단언(Assertion)

단언이란? 프로그래머 자신이 전개하고 있는 코드 내용에서 프로그래머 자신이 생각하고 있는 움직임과 그리고 특정 지점에서의 프로그램상의 설정 값들이 일치하고 있는지를 검사할 수 있도록 하는 것이 바로 Assertion이다. 예를 들자면 어느 특정 메서드의 인자 값은 10이상이어야 한다는 프로그래머의 확고함이 있다고 하자! 이럴 때 Assertion을 사용하여 프로그래머가 주장하는 확고함을 조건으로 명시하고 그 조건을 만족할 때만 코드가 실행할 수 있도록 하는 것이 Assertion이다.

단언과 예외(Exception)의 차이점은 무엇일까? 예외(Exception)는 특정한 코드에서 예외가 발생하므로 일어나는 비 정상적인 프로그램 종료와 같은 1차적인 손실을 막고 예외에 대한 처리로 인해 프로그램의 신뢰성을 높이는 것이다. 하지만 단언은 어떤 결과를 위해 특정 코드나 변수의 값을 프로그래머가 예상하는 값이어야 하는 것을 검증하는 것에 차이가 있다.

 

14. 단언의 문법
단언의 문법은 다음 두 가지로 나눈다.
assert [boolean식];
[boolean식]은 항상 true아니면 false인 boolean형의 결과를 가지는 표현식이 되어야 한다.
만약 boolean식의 결과가 false일 경우에는 AssertionError가 발생하여 수행이 정상적으로 진행되지 않는다.

assert [boolean식] : [표현식];
[boolean식]의 결과값이 false일 경우에 [표현식]을 수행한다. 여기에는 일반 값일 수도 있고 특정 메소드를 호출하여 받은 반환 값일 수도 있다. [표현식]에는 문자열로 변환이 가능한 값이 무조건 와야 한다.

 

간단한 예문
assert var>10;
assert var<10 : “10보다 작은 값이어야 함!”;
assert str.equals(“”);
assert !str.equals(“”);
assert str != null : “str에 null값이 들어오면 안됨!”;

 

15. 컴파일 및 실행 법
기본적으로 자바 컴파일러는 ‘단언’기능을 수행하지 않으면서 컴파일을 하게 되어 있다. 그러므로 컴파일러에게 ‘단언’기능을 부여하면서 컴파일을 수행하도록 하기 위해서는 다음과 같은 옵션을 주어야 한다.
java –source 1.5 [소스파일명]

실행 할 때도 마찬가지로 다음과 같이 옵션을 주면서 실행해야 한다.
java –ea [클래스명]

-ea : Enable Assertions라고 해서 단언기능을 사용 가능하게 하는 옵션이다.
-da : Disable Assertions라고 해서 ea의 반대 옵션이다.

 

그럼 2단에서 9단까지만 입력 받아 처리 하도록 범위를 설정하는 부분에 단언 기능을 부여 하는 구구단 예제를 구현해 보자!

UserExceptionTest.java

01  import static java.lang.System.out;
02  class AssertTest2 {
03      public void gugu(int dan){
04	assert dan > 1 && dan < 10 : "2~9단중 하나를 입력하세요";
05	out.println(dan+"단");
06	out.println("--------------");
07	StringBuffer sb = new StringBuffer();
08	for(int i=0;i<9;i++){
09	   sb.delete(0,sb.length());
10	   sb.append(dan);
11	   sb.append("*");
12	   sb.append(i+1);
13	   sb.append("=");
14	   sb.append(dan*(i+1));
15	   out.println(sb.toString());				
16	}
17      }
18      public static void main(String[] args){
19
20	AssertTest2 at = new AssertTest2();
21	try{
22	   int dan = Integer.parseInt(args[0]);
23	   at.gugu(dan);
24	}catch(Exception e){
25	   e.printStackTrace();
26	}
27      }
28  } 

실행결과

Exception in thread "main" java.lang.Assertionerror: 2~9단중 하나를 입력하세요

   at AssertTest2.gugu(AsserTest2.java : 5)

   at AssertTest2.main(AssertTest2.java: 25)

이렇게 해서 ‘단언’에 대해 공부해 보았고 이는 예외적인 것들을 하나씩 객체화 하여 그것을 처리하게 하는 ‘예외처리’와는 다소 차이가 있음을 알았다.
정리를 해보면 단언은 프로그래머의 확고함을 검증하고 그 사실을 인정하여 프로그램의 신뢰성을 높였지만 사실 약간의 번거로움이 있어 사용자들로 하여금 이점은 인정하지만 외면당하는 경향이 있다.

 

요약

● 패키지(Package)는 서로 관련된 클래스들과 인터페이스들을 한 곳에 두고 관리 또는 접근을 용이하게 하기 위해 준비하는 상자들과 같은 것이다

● try brace 뒤에는 반드시 catch brace 또는 finally brace가 따라가 주어야 한다.

● 하나의 try brace뒤에 catch brace가 여러 개 붙어도 상관은 없으나 가장 하위의 예외 객체부터 정의되는 것이 catch에 유익하다.

● throws는 예외 객체를 양도 하는 것이지 예외 처리가 아니므로 이를 받는 곳에서는 언젠가 try~catch를 사용하여 처리에 대한 마무리를 가져와야 한다.

● finally영역은 예외 발생 유무에 상관없이 무조건 처리되는 영역이다.

● 단언(Assertion)은 프로그래머가 주장하는 확고함을 조건으로 명시하고 그 조건을 만족할 때만 코드가 실행할 수 있도록 하는 하나의 검증제도이다.

● 단언의 2가지 문법
assert [boolean식];
[boolean식]은 항상 true아니면 false인 boolean형의 결과를 가지는 표현식이 되어야 한다.
만약 boolean식의 결과가 false일 경우에는 AssertionError가 발생하여 수행이 정상적으로 진행되지 않는다.

assert [boolean식] : [표현식];
[boolean식]의 결과값이 false일 경우에 [표현식]을 수행한다. 여기에는 일반 값일 수도 있고 특정 메소드를 호출하여 받은 반환 값일 수도 있다. [표현식]에는 문자열로 변환이 가능한 값이 무조건 와야 한다.

 

+ Recent posts