2010-09-10 51 views
16

這使我困惑。我有一個自定義註釋類,我似乎無法驗證註釋是否存在。我在這裏做錯了什麼?如果我運行MyOperationTest(見下文),我得到這樣的結果:註解隱形?

implements Library.Operation: true 
has @Library.Marker: false 
Tada! 

Library.java:

package com.example.gotchas; 

public class Library { 
    private Library() {} 

    public @interface Marker {} 

    public interface Operation { 
     public void execute(); 
    } 
} 

MyOperation.java:

package com.example.gotchas; 

@Library.Marker 
public class MyOperation implements Library.Operation { 
    @Override public void execute() { 
     System.out.println("Tada!"); 
    } 
} 

MyOperationTest。 java:

package com.example.gotchas; 

public class MyOperationTest { 
    static public void main(String[] args) 
    { 
     try { 
      Class<?> cl = Class.forName("com.example.gotchas.MyOperation"); 
      boolean implementsLibraryOperation = 
       Library.Operation.class.isAssignableFrom(cl); 
      boolean hasLibraryMarker = 
       cl.isAnnotationPresent(Library.Marker.class); 
      System.out.println("implements Library.Operation: " 
        +implementsLibraryOperation); 
      System.out.println("has @Library.Marker: "+hasLibraryMarker); 
      if (implementsLibraryOperation) 
      { 
       Class<? extends Library.Operation> opClass = 
        cl.asSubclass(Library.Operation.class); 
       Library.Operation op = opClass.newInstance(); 
       op.execute(); 
      } 
     } 
     catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
     catch (InstantiationException e) { 
      e.printStackTrace(); 
     } 
     catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

回答

26

你必須定義@Retention您的註釋:

@Retention(RetentionPolicy.RUNTIME) 
public @interface Marker {} 

否則,註釋不會在運行時保留。

(您也可以增加明確@Target(ElementType.TYPE)如果你想限制你的註釋的使用只在班)

一點題外話 - 它不是一個常見的做法是定義註釋作爲內部類。

+0

同意。默認情況下,註釋不會通過運行時保留......在編譯時它會被刪除。因此,當您運行測試代碼時,註釋不再是已編譯代碼的一部分。 – RonU 2010-09-10 21:40:52

+4

[RetentionPolicy javadoc](http://download.oracle.com/javase/6/docs/api/java/lang/annotation/RetentionPolicy.html)中的更多詳細信息:* RUNTIME - 註釋記錄在類文件中由編譯器在運行時由VM保留,所以**它們可能反射性地被讀取**。* – BalusC 2010-09-10 21:44:24

+0

啊!謝謝!!!!! – 2010-09-10 21:55:45

2

默認情況下,註釋保留策略是CLASS,它不會使您的註釋可用於反射。聲明註釋時應該限定它。