2016년 7월 8일 금요일

Java 1.4 추가 기능 - assertion

Java 1.4 추가 기능 - assertion

assertion를 사용한 프로그램밍
설명(공식설명사이트 영문, 한글)
단언을 시험할 때 사용한다고 볼 수 있다. 예를 들면 물은 위에서 반드시 아래로 떨어진다것은 반드시 사실이어야 한다.
형식
Format1
assert Expression1;
Format2
assert Expression1:Expression2;
Expression1 boolean , Expression2 값을 가지는 식, void 선언되는 식을 사용 불가 Expression2 오류 출력시 오류 설명 문자열로 사용됨. 사용된다.
Exception in thread "main" java.lang.AssertionError: Expression2
at assert_test.AssertionTestDrive.testAssertion_01(AssertionTestDrive.java:25)
assertion을 사용하지 말아야 하는 경우
  • public 메소드의 내에 인수 체크
    • AssertionError는 Error 상속 한다. (주의) 일반적인 Exception으로 예외 처리 되지 않음.
  • 어플리케이션의 올바른 동작에 필요한 처리를 실행하기 위해서 assertion를 사용하지 말아 주세요.

사용예
  • 내부의 불변조건 : 반드시 될수 없는 조건
  • 제어 플로우의 불변 조건 : 제어 흐름상 올 수 없는 곳
  • 사전 조건,사후 조건, 및 클래스의 불변 조건
    • 사전 조건 - 메소드가 호출 되었때 반드시 만족 해야 한다.
      • 락 상태 사전 조건 : Thread.holdsLock():
    • 사후 조건 - 메소드가 호출 된 후 반드시 만족 해야 한다.
    • 클래스 불변 조건 - 내부 불변 조건의 일종
내부의 불편조건 예1)
for(int i = 0 ; i < 10 ; i++){
 if(i % 3 == 0){
   System.out.printf("%d는 3으로 떨어집니다.\n",i);
 }else if(i % 3 == 1){
   System.out.printf("%d의 나머지가 1입니다.\n",i);
 }else{
   System.out.printf("%d의 나머지가 2입니다.\n",i);
   assert i % 3 == 2 : i;
 }
}
내부의 불편조건 예2)
enum Suit{ CLUBS,DIAMONDS,HEARTS,SPADES }
for(Suit suit:Suit.values()){
 switch(suit){
 case CLUBS: System.out.println(suit); break;
 case DIAMONDS: System.out.println(suit); break;
 case HEARTS: System.out.println(suit); break;
 case SPADES: System.out.println(suit); break;
 //디폴드 값이 절대로 올수 없으므로
 default:
   throw new AssertionError(suit);
 // assert false:suit; //동일함.
 }
}

제어 플로우의 분편조건 예)
for(Suit suit:Suit.values()){
 if(suit == Suit.SPADES)
   return;
}
//Never reach this point!! -->
assert false;

사전 조건 예)
public void setRefreshRate(int rate){
 //precondition -- 이 부분에서 사용하지 않는 이유는 public
 //에서 파라미터 확인을 위해서 assertion을 사용하지 말라
 //그 이유는 throw 하지 않기 때문에
 if(rate <= 0 || rate > MAX_REFRESH_RATE)
   throw new IllegalArgumentException("Illegal rate: "+rate);
 setRefreshInterval(100/rate);
}
private void setRefreshInterval(int interval){
 assert interval > 0 && interval <= 100/MAX_REFRESH_RATE : interval;
}


assert 고도의 사용법
assert 클래스 파일로 부터 무효화 하기 : 이유는 프로그램 사이즈가 작아진다.
static final boolean asserts = false;
static void controlAssert(){
 if(asserts) assert false;
}
assertion 무조건 유효화 하기 : -ea을 활성해야 한다. 않그러면 정상적으로 동작 하지 않는다.
static{
 boolean assertEnabled = false;
 assert assertEnabled = true; //
 if(!assertEnabled) throw new RuntimeException("Asserts must be enabled!!!");
}

시작시 assert를 유효화 무효화 할 수 있음. 관련 기능
디폴트는 무효화 입니다.
  • 유효화 : -enableassertions 혹은 -ea
  • 무효화 : -disableassertions 혹은 -da
모든 시스템 클래스에 대한 유효/무효화
  • 유효화 : -enablesystemassertions 혹은 -esa
  • 무효화 : -disablesystemassertions 또는 -dsa
옵션 형식 :
  • 인수 없음 : 시스템 클래스를 제외한 모든 클래스내의 assertion를 유효 또는 무효로 한다
  • packageName... : 이름 첨부의 패키지내 및 임의의 서브 패키지내의 assertion를 유효 또는 무효로 합니다.
  • ... : 현재의 작업 디렉토리내의 이름이 없는 패키지내의 assertion를 유효 또는 무효로 한다
  • className : 지정한 클래스내의 assertion를 유효 또는 무효로 한다
사용예

  • 1) java -ea:com.wombat.fruitbat... BatTutor
    • - 설명 : com.wombat.fruitbat 패키지와 그 서브 패키지내에서만 assertion를 유효하게 함. 실행프로그램 BatTutor
  • 2) java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat BatTutor
    • - 설명 : com.wombat.fruitbat 패키지내의 assertion를 유효하게 하고,com.wombat.fruitbat.Brickbat 클래스내의 assertion를 무효로 시킨 후 BatTutor를 실행함