注释作为对象的替代品?
Annotations as a substitute for Objects?
最近我尝试使用Picocli实现命令行应用程序。这个库使用注解来定义命令、选项等
我以前从未研究过注释,这个库激起了我的好奇心。既然自己在尝试自己的东西,我不禁要问:如果我需要一个对象来纯粹存储数据,那么创建一个class 还是定义一个注解更好?
现在,我了解到您需要反射才能在运行时访问注释,这非常昂贵。但是说你加载它们一次并存储在内存中;例如在 Set<@Option>
中。它们会比普通物体更轻还是更轻?
例如:
@Target( { ElementType.FIELD, ElementType.METHOD} ) @Retention(RetentionPolicy.RUNTIME)
public @interface Option {
String DEFAULT_STRING = "";
String name();
String description() default DEFAULT_STRING;
String [] params() default {};
}
对比
public class Option {
private final String name;
private String description;
private String [] params;
public Option(String name) {
this.name = name;
}
public Option (String name, String description, String [] params) {
this(name);
this.description = description;
this.params = Arrays.copyOf(params, params.length);
}
// Getters & Setters
}
然后...
public class Foo {
@Option(name = "var", description = "var description")
private boolean var;
public Foo() {
Option option = new Option("var", "var description", new String[0]);
}
}
注释比具有普通字段的自定义 class 占用的内存略多。这是因为注解是一个接口,Java会为每个带有RUNTIME保留的注解实例生成一个java.lang.reflect.Proxy
。该代理的 AnnotationInvocationHandler
将数据值存储在 LinkedHashMap
.
中
因此涉及的对象更多,并且它们比普通 class 占用更多 space。
最近我尝试使用Picocli实现命令行应用程序。这个库使用注解来定义命令、选项等
我以前从未研究过注释,这个库激起了我的好奇心。既然自己在尝试自己的东西,我不禁要问:如果我需要一个对象来纯粹存储数据,那么创建一个class 还是定义一个注解更好?
现在,我了解到您需要反射才能在运行时访问注释,这非常昂贵。但是说你加载它们一次并存储在内存中;例如在 Set<@Option>
中。它们会比普通物体更轻还是更轻?
例如:
@Target( { ElementType.FIELD, ElementType.METHOD} ) @Retention(RetentionPolicy.RUNTIME)
public @interface Option {
String DEFAULT_STRING = "";
String name();
String description() default DEFAULT_STRING;
String [] params() default {};
}
对比
public class Option {
private final String name;
private String description;
private String [] params;
public Option(String name) {
this.name = name;
}
public Option (String name, String description, String [] params) {
this(name);
this.description = description;
this.params = Arrays.copyOf(params, params.length);
}
// Getters & Setters
}
然后...
public class Foo {
@Option(name = "var", description = "var description")
private boolean var;
public Foo() {
Option option = new Option("var", "var description", new String[0]);
}
}
注释比具有普通字段的自定义 class 占用的内存略多。这是因为注解是一个接口,Java会为每个带有RUNTIME保留的注解实例生成一个java.lang.reflect.Proxy
。该代理的 AnnotationInvocationHandler
将数据值存储在 LinkedHashMap
.
因此涉及的对象更多,并且它们比普通 class 占用更多 space。