SSISO Community

시소당

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  문  안의  내용이  실행  되게  되면서  런타임  예외를  실행  시켜줄수  있을것이다.






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

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



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

[출처]  Assert  사용하기  -  JDK  1.4  이상  지원|작성자  찬
http://blog.naver.com/changgaman?Redirect=Log&logNo=60001988495

529 view

4.0 stars