2014-02-06 69 views
0

在下面的代碼打印註釋繼承作用怪異

@MyTestAnnotation():MyTestAnnotation是否被指定爲@Inherited或不FOO

兩個類B和C的。 我認爲只有在@Inherited被指定的情況下才會繼承註釋,並且默認的註釋繼承行爲是它們沒有被繼承。這裏發生了什麼事?

import java.lang.annotation.Annotation; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import java.lang.reflect.Method; 

public class AnnotationTest { 

    public static void main(String[] args) { 
     B b = new B(); 
     C c = new C(); 
     printMethdodsAndAnotations(b); 
     printMethdodsAndAnotations(c); 
    } 

    public static void printMethdodsAndAnotations(Object obj) { 
     Method[] methods = obj.getClass().getMethods(); 
     for (int i = 0; i < methods.length; i++) { 

      Annotation[] annotations = methods[i].getAnnotations(); 
      if (annotations.length > 0) 
      {        
       for (int j = 0; j < annotations.length; j++) { 
        System.out.println(annotations[j].toString() + ":" + methods[i].getName()); 
       } 
      } 
     } 
    } 
} 

//@Inherited 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
@interface MyTestAnnotation { 

} 

abstract class A { 
    public abstract void foo(); 
} 

class B extends A { 

    @MyTestAnnotation  
    public void foo() { 
     System.out.println("B's foo()"); 
    } 
} 

class C extends B { 

    public void foo2() { 
     System.out.println("C's foo()"); 
    } 
} 
+0

繼承的註釋只適用於類,而不適用於方法。在這兩種情況下,您都顯示相同foo方法的註釋,因此邏輯上註釋是相同的。繼承的javadoc明確指出:'請注意,如果註釋類型用於註釋除類之外的其他任何內容,則此元註釋類型不起作用。 「 –

回答

1

由於C不會覆蓋B#foo(),它繼承它。它也繼承了它的一切,即。註釋。如果添加

public void foo() { 
    System.out.println("C's foo()"); 
} 

C,它不會有註釋。

你會發現,如果你打印出來

System.out.println(annotations[j].toString() + ":" + methods[i]); // instead of methods[i].getName() 

它打印

@MyTestAnnotation():public void com.sc.B.foo() 

的方法是B的方法。並B#foo是非常多註釋@MyTestAnnotation


另外,@Inherited用於類別註釋。正如Javadoc中說明

請注意,此元註釋類型沒有影響,如果註釋 類型用於註釋不是類的任何其他。