附加到新对象的 Java 注释?

标签 java object annotations

是否可以将注释附加到新对象?

假设我们有一个简单的房子对象,House house = new House () 和注释 @Large@Spooky

我的想法是有一个 switch 语句,所以标记为 @Spooky 的房子与标记为 @Large 的房子做的事情不同。

@Spooky
House house = new House();

System.out.println(house.getClass().getAnnotations().length);

显然我的新房子对象上没有注释 length == 0

这是为什么呢?

最佳答案

总则

您不能注释对象(仅在运行时存在)。您只需注释一个声明,或者从 Java 8 开始,注释一个类型用法(在编译时已经存在)。

参见 The Java™ Tutorials, Annotations, Annotations Basics :

Where Annotations Can Be Used

Annotations can be applied to declarations: declarations of classes, fields, methods, and other program elements. [...] As of the Java SE 8 release, annotations can also be applied to the use of types.

The Java™ Tutorials, Annotations, Type Annotations [...] :

Before the Java SE 8 release, annotations could only be applied to declarations. As of the Java SE 8 release, annotations can also be applied to any type use. This means that annotations can be used anywhere you use a type. A few examples of where types are used are class instance creation expressions (new), casts, implements clauses, and throws clauses. This form of annotation is called a type annotation [...].

和可靠的最终来源The Java® Language Specification, 9.6.4. Predefined Annotation Types :

9.6.4.1. @Target

Annotation types may be applicable in declaration contexts, where annotations apply to declarations, or in type contexts, where annotations apply to types used in declarations and expressions.

[我强调的。]

回答你的问题

正如@M.Prokhorov 在他对你的问题的评论中提到的,你不是在注释你的 House 类,而是注释 house 的局部变量声明,即 房子

另见 Java Annotations Tutorial :

Annotation Placement

You can place Java [declaration] annotations above classes, interfaces, methods, method parameters, fields and local variables. [...]

Creating Your Own Annotations

[...]

@Retention

[...]

@Retention(RetentionPolicy.RUNTIME)

This is what signals to the Java compiler and JVM that the annotation should be available via reflection at runtime.

[...]

RetentionPolicy.CLASS means that the annotation is stored in the .class file, but not available at runtime. This is the default retention policy, if you do not specify any retention policy at all.

[我强调的。]

这意味着您必须声明您的 Spooky 注释:

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

但是,正如@LouisWasserman 在他对您的问题的评论中提到的那样:

I don't believe there's any way to get the annotations from a local variable.

另见 SO 问题 ElementType.LOCAL_VARIABLE annotation type和前面提到的 JLS:

9.6.4.1. @Target

[...]

An annotation on a local variable declaration is never retained in the binary representation.

因此,如果您将 house 设为字段(又名成员变量):

@Spooky
private House house = new House();

你可以使用:

Stream.of( this.getClass().getDeclaredFields() )
    .forEach( field -> Stream.of( field.getAnnotations() )
        .forEach( annotation -> System.out.printf( "@%s%n%s %s %s;%n",
            annotation.annotationType().getSimpleName(),
            Modifier.toString( field.getModifiers() ),
            field.getType().getSimpleName(),
            field.getName() ) ) );

或者如果你想专门获取 house 字段:

try {
    final Field field = this.getClass().getDeclaredField( "house" );
    final Spooky spooky = field.getAnnotation( Spooky.class );
    if ( spooky != null ) {
        System.out.printf( "@%s%n%s %s %s;%n",
            spooky.annotationType().getSimpleName(),
            Modifier.toString( field.getModifiers() ),
            field.getType().getSimpleName(),
            field.getName() );
    }
}
catch ( NoSuchFieldException | SecurityException e ) {
    e.printStackTrace();
}

两种情况下的输出:

@Spooky
private House house;

但是,如您所见,即使有了流的简洁性,您的代码也不会变得更清晰。我会考虑在评论中对您的问题提出的建议。

关于附加到新对象的 Java 注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42585120/

相关文章:

javascript - JSON 响应与颜色数据的部分键不正确匹配

r - 将字符向量转换为不带引号的对象名称

java - 是否可以创建一个 Java 注释,其属性可以是任何注释?

java - 注解会影响 Java 默认序列化吗?

java - 在本地开发中使用 Docker

c# - 在 C# 中从字符串创建动态类型

java - 确保 Java 类不从某些包中导入

java - 在spring security中使用自定义方法安全注解

java - Tomcat7 上的 JSF 与 Java6 系统时间显示委内瑞拉时间

Javafx TableView 始终为空