java – 用于实现注释的用例

什么是实现注释的有效用例?

在主要设计基于注释的配置系统时,我偶尔需要创建实现代码生成或编程配置注释的类。

替代方法包括将注释中包含的数据镜像到DTO中,这似乎是一个开销。

这里是一个例子:

public enum IDType {
    LOCAL,
    URI,
    RESOURCE;
}

@Documented
@Target( { METHOD, FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Id {
    /**
     * @return
     */
    IDType value() default IDType.LOCAL;
}

与实现

public class IdImpl implements Id{

    private final IDType idType;

    public IdImpl(IDType idType){
        this.idType = idType;
    }

    @Override
    public IDType value() {
        return idType;
    }

    @Override
    public Class<? extends Annotation> annotationType() {
        return Id.class;
    }

}

我得到编译器警告,但它似乎是一个有效的工具,许多用例。

上面示例的警告是

The annotation type Id should not be
used as a superinterface for IdImpl

编辑:

我刚从Guice发现这个例子:

bind(CreditCardProcessor.class)
    .annotatedWith(Names.named("Checkout"))
    .to(CheckoutCreditCardProcessor.class);

Javadoc from Names

有没有人一些信息为什么这种限制存在或有一些其他用例在心?

我从来没有在实践中使用它,但你得到的是,你可以使用类作为替换您的注释。

让我们创建一个人工示例。假设我们有一个文档生成器。它从给定类读取一个@Docu注释,并打印描述属性。喜欢这个:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;

public class DokuGenerator {

    public static void main(String[] args) throws Exception {
        new DokuGenerator(StaticClass.class, StaticClass2.class);
    }

    public DokuGenerator(Class<?>... classesToDokument) throws Exception {
        List<Docu> documentAnnotations = getDocumentAnnotations(classesToDokument);
        printDocumentation(documentAnnotations);
    }

    private List<Docu> getDocumentAnnotations(Class<?>... classesToDokument)
            throws Exception {
        List<Docu> result = new ArrayList<Docu>();
        for (Class<?> c : classesToDokument)
            if (c.isAnnotationPresent(Docu.class))
                result.add(c.getAnnotation(Docu.class));
        return result;
    }

    private void printDocumentation(List<Docu> toDocument) {
        for (Docu m : toDocument)
            System.out.println(m.description());
    }

}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Docu {
    String description();
}

@Docu(description = "This is a static class!")
class StaticClass {
}

@Docu(description = "This is another static class!")
class StaticClass2 {
}

打印:

This is a static class!  
This is another static class!

我们现在想要实现的是,一个类不仅可以是静态注释的,而且可以将运行时信息添加到文档中。我们非常高兴地使用@Docu注释大多数时间,但有特殊情况下,我们想要特殊的文档。我们可能想为某些方法添加性能文档。我们可以通过让类实现注释来做到这一点。生成器首先检查注释,如果不存在,则检查该类是否实现注释。如果是,它将类添加到注释列表。

像这样(在生成器中只有两行代码):

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.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DokuGenerator {

    public static void main(String[] args) throws Exception {
        new DokuGenerator(StaticClass.class, StaticClass2.class,
                DynamicClass.class);
    }

    public DokuGenerator(Class<?>... classesToDokument) throws Exception {
        List<Docu> documentAnnotations = getDocumentAnnotations(classesToDokument);
        printDocumentation(documentAnnotations);
    }

    private List<Docu> getDocumentAnnotations(Class<?>... classesToDokument)
            throws Exception {
        List<Docu> result = new ArrayList<Docu>();
        for (Class<?> c : classesToDokument)
            if (c.isAnnotationPresent(Docu.class))
                result.add(c.getAnnotation(Docu.class));
            else if (Arrays.asList(c.getInterfaces()).contains(Docu.class))
                result.add((Docu) c.newInstance());
        return result;
    }

    private void printDocumentation(List<Docu> toDocument) {
        for (Docu m : toDocument)
            System.out.println(m.description());
    }

}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Docu {
    String description();
}

@Docu(description = "This is a static class!")
class StaticClass {
}

@Docu(description = "This is another static class!")
class StaticClass2 {
}

class DynamicClass implements Docu {

    public DynamicClass() {
        try {
            Thread.sleep((long) (Math.random() * 100));
        } catch (InterruptedException e) {
            // ignore exception to make debugging a little harder
        }
    }

    @Override
    public String description() {
        long millis = System.currentTimeMillis();
        new DynamicClass();
        millis = System.currentTimeMillis() - millis;
        return "This is a dynamic class. I run on "
                + System.getProperty("os.name")
                + ". The construction of an instance of this class run for "
                + millis + " milliseconds.";
    }

    @Override
    public Class<? extends Annotation> annotationType() {
        return Docu.class;
    }

}

输出为:

This is a static class!  
This is another static class!  
This is a dynamic class. I run on Windows XP. The construction of an instance of this class run for 47 milliseconds.

你不能改变代码生成器,因为你可以使用类作为注释的替换。

其他示例应该是使用注释或XML作为配置的框架。您可能有一个处理注释的处理器。如果使用XML作为配置,您可以生成实现注释的类的实例,并且您的处理器在它们上面工作,而无需一个更改! (当然还有其他方法来实现相同的效果,但这是一种方式来做到)

http://stackoverflow.com/questions/3341930/use-cases-for-implementing-annotations

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:java – 用于实现注释的用例