본문 바로가기

공부/컴퓨터

Assert 사용하기 - JDK 1.4 이상 지원

반응형

==========================================================================
이 글은 이론적으로 아는 것을 직접 설명 및 구현을 해 봄으로써 제 자신의
실력을 다지기 위한 글 입니다. 물론 정확한 이론. 용어도 아님을 밝힙니다.
이 글을 직.간접적으로 사용함으로써 발생되는 모든 불이익을 책임지지 않습니다.

문의점, 오류, 잘못된 용어들은 저의 홈페이지 Work 게시판을 이용하여 주시고
이상의 사항에 대하여는 최대한 덧글 ( 코멘트 ) 를 이용해 주십시오.

본 글은 저의 홈페이지인 http://ggaman.com 과
싸이월드의 (JPSC) JAVA program study club 에서 보실수 있습니다.

homepage : http://ggaman.com e-mail n MSN : chan at ggaman.com

20040103 - Chan
==========================================================================

안녕하세요.
찬 입니다.

오랜만에 이렇게 글을 쓰네요.

요즘에 Win32SDK API 한다고 -_-;;
크크크. 외도 중입니다. -_-;
( 오늘 메모장 거의 70% 만들었네요. 축하해 주세요 -_-; )



오늘은 Assertion 에 대하여 이야기 해 보겠습니다.
( 우리말로 읽으면 어썰션이라고 읽더군요. ^^ )


assert 는 문제가 생기면 바로 에러를 리턴해 주는것입니다.
AssertionError 이라는 클래스가 있는데. 이름에서 알수 있다시피 Error 클래스를 상속 받습니다.
( 그래서 예외도 아니고 에러가 생기는것이죠 )



assert의 사용은 아주 단순합니다.

assert (boolena-value);

저기서 boolean-value 가 false 이면 에러를 내게 되어 있습니다.



즉 반드시 처리 후에 null이 되어야 하는데
null이 되지 않을경우를 잡아낼려면 다음과 같이 할수 있습니다.


if ( someBoolen ) someObject = null;
assert someObject == null;


저기서 만약 someBoolean이 false 상태 였다면.
someObject는 당연히 어떤 객체를 가르키고 있을수 있습니다.
그렇다면 (someObject == null) 의 결과는 false 가 되는 경우도 있고,
이때에 assert 문에 의해서 에러를 내게 됩니다.



그렇다면 예외처리를 하지 말고 무언가가 잘못 되었을때
그냥 assert를 사용하면 되지 않겠느냐? 라고 생각하신다면,
알려드리는게 인지상정. ( 으윽 -_- 포켓 몬스터 -_-;; )


예외처리는 보통 내가 만든 클래스들이 잘못 사용되어지고 있을때 나타낼때 사용하게 되어 있습니다.
( 잘 생각해보시면 예외처리하는 부분들은 대부분 그렇게 쓰여지고 있습니다. )
assert는 꼭 원하는 결과가 나와야하는데 그렇지 않은 경우 ( 그래서 프로그램이 잘못 되는 경우 )에
사용하시는게 맞을꺼라고 이 연사 감히 외쳐 봅니다. -_-;;;



Assertion 은 JDK 1.4 부터 지원을 하는 것 입니다.
그래서 그 이전버젼에서 사용을 하면 당연히(!) 동작하지 않습니다.

하지만 Assertion 의 사용은 자바에서 새로 생긴것이 아니고.
이전에 있었던 언어들로 부터 계속 내려온것이라서.
많은 분들이 assert 라는 변수를 이용해서 작업을 하였을것이라 생각합니다.

다음과 같은 예제가 있습니다.


class someClass {
public static void main(String[] args)
{
int assert;
assert true;
}
}


이렇게 하신다면 컴파일 시에 JDK 1.4 이상에서는 int assert 부분에서 에러가 날것입니다.
( assert가 예약어가 되었기 때문에 변수로 사용할수 없겠죠. )
하지만 1.4 미만에서는 당연히 assert ture; 부분에서 에러가 날겁니다.


assert를 사용하는 것은 다음과 같이 컴파일 해 주어야 한다고 합니다.

javac -source 1.4 SomeCode.java


그리고 assert같은 경우는 실행 할 경우 이것을 끄고 켜는 옵션이 있습니다.
다음과 같은 예제가 있습니다.


public class SomeClass {
public static void main (String[] args) {
assert someMethod();
System.out.println("Program End");
}

public boolean someMethod() {
System.out.println("Run someMethod()");
return true;
}
}




이 예제를 컴파일 하고 ( 위와 같이 -source 1.4 를 넣어야합니다. ) 실행 시키면 다음과 같이 실행 됩니다.
java SomeClass

Program End


이상하게도 someMethod() 문이 실행되지 않는군요.
우리가 원하는 ( 또는 예상하는 ) 실행은
someMethod()가 실행 되고 화면에 Run someMethod()를 출력하고, true를 리턴 시켜서
결국 assert true; 가 되고
다시 화면에 Program End 가 출력되어야 할것입니다.


assert는 일반적으로는 실행 되지 않게 되어 있습니다.
그래서 실행할때는 다음과 같이 실행 해야 됩니다.

java -ea SomeClass

Run someMethod()
Program End


개발중일때에는 -ea 옵션을 붙여서 실행 시켜 잘못된것을 전부 찾아 보고
운영할때에는 -ea 옵션 없이 실행 시키면 됩니다.


여기서 다시 한가지 생각해 볼것이 있습니다.
그렇다면 assert가 컴파일된 class에 들어 있으니, 용량도 많고, 속도도 느릴것 아니냐? 라는 궁금증을 가지게 됩니다.
맞습니다. -ea 옵션 없이 실행 된다고해도 코드를 가지고 있으니, 당연히 그렇습니다.


이부분은 다음과 같이 해결 할수 있습니다. 요즘에 나오는 컴파일러들은 참으로 똑똑합니다.
( 아니 책들을 보니깐 그렇다고 합니다. -_-;; )

예를 들자면 다음의 예를 보겠습니다.



int i = 0;
int j = 1;

for ( i = 0 ; i< 100; i++ ) {
j=2;
}


이런 소스가 있다면 컴파일러는 다음과 같이 처리를 해 줍니다.


int i = 0;
int j = 1;
j = 2;

for ( i = 0; i < 100 ; i++ ) { }



j가 루프에서 2로 고정적이기 때문에 j=2 항목을 위로 빼버립니다.
저렇게 하면 j에 2가 100번 할당 되는게 한번만 할당되고 말죠.


이렇듯이 컴파일러는 똑똑합니다.

그래서 다음과 같이 처리하면 assert를 아무리 많이 넣어도 assert는 컴파일된 코드에 포함 되지 않게 됩니다.
( 물론 포함될수도 있지만, 전혀 성능에 영향을 미치지 못하게 될것 같습니다. ;;;;; ( 자신 없음 ) )


final boolean enableAssert = false;


if ( enableAssert ) {
assert someCompare();
}





위와 같은 코드로 작성을 한다면 enableAssert는 항상 false를 가지고 있으며
if 문의 조건 역시 항상 false 가 되므로 저 if 문 사이는 절대로 실행 될수 없다.
그러므로 컴파일러가 저 부분은 그냥 무시하게 되는 것이다.


하지만 꼭 그렇게 속도나 메모리가 문제 되지 않는다면 위와 같은 코드는 권장하지 않는다.

assert 는 실행 옵션으로 끄고 켜고를 할수 있기 때문에 굳이 저렇게 막을 필요는 없을것이다.




무조건 assert가 동작하도록 하는 방법도 있다. ( 물론 어렵지는 않다. 내가 이글을 설명할 정도라면 충분히 ;; )


static {
boolean enableAssert = false;
assert enableAssert = true;

if ( !enableAssert) {
throw new RuntimeException("Asserts must be enabled!!!");
}
}


public static void main(String[] str) {
System.out.println("Program run");
}



위와 같은 것을 컴파일 했다고 하고 -ea 옵션으로 실행 시켜 보면 다음과 같이 실행 될것이다.
-ea 옵션을 실행 시켰으니 assert 문은 실행 될것이다.
그렇다면 enableAssert 는 true가 될것이고 if 문 안의 내용은 실행 되지 않을것이다.

하지만 -ea 옵션 없이 실행 시킨다고 해 보자.
그렇다면 assert 문은 무시 될것이다. ( 이 줄은 실행되지 않을것이다. )
그러므로 enableAssert의 값은 false 가 될것이고.
if 문 안의 내용이 실행 되게 되면서 런타임 예외를 실행 시켜줄수 있을것이다.






아아. -_- 쓰다 보니 존대와 반말이 오고 갔네요 ;; 정말 죄송.

오랜만에 자바 관련 글을 정리하다 보니.
혹시 소스가 문제가 있을수 있습니다. 주로 보고 쳤지만 오타때문에 ..
( 예제는 직접 실행 시켜보지 못했음을 알립니다. -_-; )



그럼이만.
즐거운 하루 되세요.
반응형