2010-09-10 5 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

+4

Подробнее в [RetentionPolicy javadoc] (http://download.oracle.com/javase/6/docs/api/java/lang/annotation/RetentionPolicy.html): * RUNTIME - Аннотации должны быть записаны в файле класса компилятором и сохраняются VM во время выполнения **, поэтому их можно читать рефлексивно **. * – BalusC

+0

ах! благодаря!!!!! –

2

По умолчанию политика хранения аннотаций - CLASS, что не позволяет сделать вашу аннотацию доступной для отражения. Вы должны квалифицировать его при объявлении аннотации.

Смежные вопросы