gpt4 book ai didi

java - 实现注解的用例

转载 作者:IT老高 更新时间:2023-10-28 20:52:09 26 4
gpt4 key购买 nike

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

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

另一种方法是将注释中包含的数据镜像到 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 注释并打印 description 属性。像这样:

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 作为配置,您可以生成实现注释的类的实例,并且您的处理器无需任何更改即可处理它们! (当然还有其他方法可以达到相同的效果,但这是一种方法)

关于java - 实现注解的用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3341930/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com