J2SE(Java 2 Platform, Standard Edition) 1.4 버전이 되면서 자바에 간단한 검증(assertion) 기능이 추가되었다. 간단히 얘기해, 검증이란 프로그램 실행 중에 당연히 ‘참(true)’이 되어야 할 부분을 확인하는 Boolean 표현식이다. 이 검증 기능을 지원하기 위해 J2SE 1.4 에서는 assert라는 키워드와 AssertionError 클래스가 추가되었고, java.lang.ClassLoader 에도 몇 개의 메소드들이 추가되었다.
프로그램의 정확성(correctness)이란 예측하지 못한 상황에 대처할 수 있는 시스템의 능력인 신뢰성과, 견고성을 이루는 중요한 특성을 말한다.

 검증 기법은 정확한 프로그램을 구현하는데 많은 도움을 준다.
검증 기법은 개발자들이 프로그램 수행 중에 명확히 ‘참’이 될 것을 요구하는 부분이 실제로도 ‘참’이 됨을 검증하는 Boolean 표현식이다. 검증 기능을 사용함으로써 우리는 소프트웨어를 설계하고 구현함에 있어 기대치 못한 효과를 얻을 수 있다. 이 장에서 필자는 J2SE 1.4에서 새롭게 소개된 검증 기능을 사용하는 방법을 간단히 설명할 것이다. 그리고 다음 장에서는 검증 기법을 사용하는 방법론에 대해 다뤄보도록 하겠다.

검증문(Assertion) 선언

검증은 자바의 새로운 키워드 ‘assert’를 사용해 선언한다.
검증문은 다음과 같이 두 가지 형태를 갖는다.

1. assert expression1;
2. assert expression1 : expression2;

 위의 두 문장에서 expression1 이 검증이 필요한 Boolean 표현식이다. 이 표현식은 개발자가 프로그램이 수행되는 동안 항상 ‘참(true)’이 되어야 한다고 요구하는 조건이 된다. 두 번째 문장에 있는 expression2 는 검증이 실패했을 때 상세 정보를 표현하기 위한 메시지로 String으로 변환 가능한 형태여야 한다. 다음은 첫 번째 형태의 검증문에 대한 예제들이다.
 아래 예제는 m1(int) 메소드에서 검증문을 사용하고 있다.

public class Foo {
 public void m1( int value ) {
  assert 0 <= value; System.out.println( "OK" );
 }
 public static void main( String[] args ) {
  Foo foo = new Foo();
  System.out.print( "foo.m1( 1 ): " );
  foo.m1( 1 );
  System.out.print( "foo.m1( -1 ): " );
  foo.m1( -1 );
 }
}
 main() 함수는 mi(int) 메소드를 두 번 호출한다. 한 번은 양수, 한 번은 음수를 입력값으로 주고 있는데 음수값이 들어올 경우는 검증 오류가 발생할 것이다. 'assert'는 새로 도입된 키워드이기 때문에 이 예제를 실행시켜 보기 위해서는 J2SE 1.4와 호환되는 컴파일러를 사용해야 한다. 또한 ‘–source 1.4’ 라는 명령행 옵션을 주어 컴파일 시 검증 기능을 사용할 것임을 명시해야 한다. 옵션을 통해 검증을 지원하는 이유는 하위 호환성을 때문이다. 기본적으로(‘-source 1.4’ 옵션을 주지 않았을 경우) J2SE 1.4 컴파일러는 검증문을 허용하지 않는다. 하지만 소스 코드에 식별자나 레이블로 ‘assert’ 를 사용하고 있다면 컴파일러가 경고를 할 것이다.

즉, 이와 같은 경우 비록 1.3 이전의 컴파일러가 문제 없이 컴파일 했던 소스 코드라 하더라도 1.4의 컴파일러가 거부하게 된다. 단, JVM은 이를 구분하지 않기 때문에 이미 컴파일이 되어 있는 class 파일들을 수행시키는 데는 문제가 없다. 다음 명령은 Foo.java를 컴파일한다. Javac –source 1.4 Foo.java 컴파일된 Foo.class 파일의 m1(int) 메소드는 검증 코드를 포함하고 있다. 하지만 컴파일러와 마찬가지로, 자바 가상 머신(Java Virtual Machine, 이하 VM) 역시 기본적으로는 검증 기능 수행하지 않는다. 다시 말해 자바의 환경이 기본적으로는 검증을 하지 않도록 설정되어 있다는 애기다. 이와 같은 하위 호환 정책은 시대에 좀 뒤쳐진 것이 아닌가 하는 생각이 들게 한다. 검증 기능은 자바에서 기본적으로 지원해야 할 만한 충분한 가치가 있다. 하위 호환을 위해서라면 컴파일 옵션으로 ‘-source 1.3’처럼 써야 하고 VM 역시 마찬가지이다. 하위 호환성에 대한 압박은 충분히 이해 하지만 예외적인 상황으로 치부되기엔 너무 중요한 기능이 아닌가 싶다.
검증 기능 활성화

VM은 명령행 옵션에 따라 개개의 클래스 단위로 검증 기능을 활성/불활성화 시킬 수 있다. ‘-enableassertions’ 나 짧게 ‘-ea’ 옵션은 검증 기능을 활성화 시킨다. 다음과 같은 형태로 사용할 수 있다(본 글에서는 단축 형태로 사용하겠다).

1. –ea
2. –ea: <class>
3. –ea:...
4. –ea:<package>...
 첫 번째 형태는 시스템 클래스를 제외한 모든 클래스들을 검증하도록 한다. 시스템 클래스들은 ‘-enablesystemassertions’나 ‘-esa’ 라는 별도의 옵션을 사용해야 한다. 시스템 클래스들을 별도로 취급하는 이유는 개발자들이 자바의 시스템 라이브러리에서의 검증 에러를 의심할 만한 상황은 거의 발생하지 않기 때문이다.

 두 번째 형태는 명시된 클래스만을 검증한다. 마지막 두 경우는 패키지 단위의 설정 옵션으로, 세 번째는 기본 패키지를, 네 번째는 명시된 패키지를 검증한다.
두 번째와 네 번째의 사용시 주의해야 할 점은 VM이 명시된 클래스나 패키지가 실제로 존재하는 지 여부는 확인하지 않는다는 것이다. 우선 간략히 설명하고 자세한 내용은 글의 마지막 부분에서 다시 언급하겠다. ClassLoader 클래스는 클래스와 패키지 이름과 그 검증 여부에 대한 맵(map)을 갖고 있다. 클래스 로더(ClassLoader의 하위 클래스)들은 하나의 클래스를 읽어 들일 때, 해당 클래스명이 이 맵의 엔트리로 존재하는 지 여부를 판단한다. 따라서 맵에 존재하는 않는 클래스나 패키지는 절대 검증이 일어나지 않게 된다. 특이하게도 VM은 클래스나 패키지명을 해석할 때 실제 시스템에 존재하는 지 여부는 확인하지 않는다(역자주> 원격 객체를 통해 현 시스템에는 존재하는 않는 새로운 클래스나 패키지들을 동적으로 사용할 수 있기 때문이다).
 패키지 단위의 검증 옵션에서 ‘*’ 가 아닌 ‘...’가 사용되고 있음을 집고 넘어가 보자. 추적을 뜻하는 ‘...’는 자바 검증 메커니즘의 특징 중 하나로 명시된 패키지 뿐 아니라 그 하위의 모든 패키지들을 검증하도록 지정한다. 예를 들어 ‘-ea:javax.swing...’라는 옵션은 모든 Swing 패키지들을 검증하도록 할 것이고, ‘-ea:javax.xml...’ 옵션이 주어지면 J2SE 1.4의 다섯 XML 패키지들에 대해 검증을 수행한다. 주제와 관련은 없지만 한 가지 재미있는 것은 javax.xml 밑의 다섯 패키지들은 javax.xml의 하위 패키지라 생각되지만 실상 javax.xml이라는 패키지는 존재하지도 않는다.
다음은 아무 옵션을 주지 않고 ‘Foo’를 실행시킨 결과이다(VM은 기본적으로 검증을 수행하지 않는다).

foo.m1( 1 ): OK
foo.m1( -1 ): OK

 검증 기능이 불활성 상태이므로 두 번의 m1(int) 메소드 호출 모두 검증되지 않았다. 앞서 설명했듯이 검증을 하려면 별도의 명령행 옵션을 주어야 한다. 다음 셋 중 어떤 식으로든 Foo 클래스를 검증할 수 있다.

java –ea Foo
java –ea:Foo Foo
java –ea:... Foo

실행 결과를 보자.

foo.m1( 1 ): OK
foo.m1( -1 ): Exception in thread “main” java.lang.AssertionError
at Foo.m1(Foo.java:6)
at Foo.main(Foo.java:17)


 ‘1’을 인자로 주었을 경우는 무사히 검증을 통과했지만, ‘-1’이 주어지니 ‘인자는 양의 정수여야 한다’는 제약에 걸리게 되었다. 따라서 VM은 java.lang.AssertionError를 던져 검증이 실패했음을 알린다.

scjp를 공부하면서 처음 보는 내용이고, JAVA책에서도 찾기가 쉽지 않아서..
검색을 통해 대략적인 편집을 해보았다. 더 자세한 내용은
http://www.gosinfo.com/zb41/zboard.php?id=scjp&no=26 을 참고하세요..