27 1月 2010

Java Annotation: Inherited

java.lang.annotation中@Retention跟@Target都很容易瞭解,但@Inherited就比較麻煩些,所以簡單列個例子來看@Inherited的影響。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
public @interface InheritedAnn {

}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface NonInheritedAnn {

}
上列兩個Annotation僅差別在有無@Inherited。簡單看一下@Inherited對extends跟implements的影響
@InheritedAnn
@NonInheritedAnn
public class Parent {
 
 @InheritedAnn
 @NonInheritedAnn
 public void notBeOverrided() {}
 
 @InheritedAnn
 @NonInheritedAnn
 public void beOverrided() {}
}

public class Child extends Parent {
 @Override
 public void beOverrided() {}
}


@InheritedAnn
public interface SimpleInterface {
 @InheritedAnn
 void simple();
}

public class SimpleImpl implements SimpleInterface {
 @Override
 public void simple() {}
}
寫個Test吧
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.fail;

import java.lang.reflect.Method;

import org.junit.Test;
public class AnnTest {
 /**
  * 驗証具有@Inherited 的Annotation可以透過extends保留在subclass中
  */
 @Test
 public void testConcreteClassInheritence() throws Exception {
  //測試Annotated Type,僅具有@Inherited會被保留
  assertNotNull(Child.class.getAnnotation(InheritedAnn.class));
  assertNull(Child.class.getAnnotation(NonInheritedAnn.class));
  //測試沒被Override 的Annotated Method,無論是否有@Inherited皆會被保留
  Method notBeOverrided = Child.class.getMethod("notBeOverrided", null);
  assertNotNull(notBeOverrided.getAnnotation(InheritedAnn.class));
  assertNotNull(notBeOverrided.getAnnotation(NonInheritedAnn.class));
  //測試被Override 的Annotated Method,無論是否有@Inherited皆不會被保留
  Method beOverrided = Child.class.getMethod("beOverrided", null);
  assertNull(beOverrided.getAnnotation(InheritedAnn.class));
  assertNull(beOverrided.getAnnotation(NonInheritedAnn.class));
 }
 
 /**
  * 驗証即便具有@Inherited 的Annotation仍無法透過implements interface保留
  */
 @Test
 public void testInterfaceInheritence() throws Exception {
  //無論是Type或Method皆無法保留Annotation
  //測試Annotated Type
  assertNull(SimpleImpl.class.getAnnotation(InheritedAnn.class));
  //測試Annotated Method
  Method simple = SimpleImpl.class.getMethod("simple", null);
  assertNull(simple.getAnnotation(InheritedAnn.class));
 }
}

要說的都寫在Test中...

沒有留言: