用户注释如何工作?

Sco*_*ain 9 java annotations

我仍然是Java编程的新手,我正在查看一个开源项目并遇到了这个问题

public @TileNetworkData int progressPart = 0;   
Run Code Online (Sandbox Code Playgroud)

我已经看过@以前的使用,但只是做@override成员之前的事情.令我惊讶的是查找了它带给我用户代码的定义

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TileNetworkData {

    int staticSize () default -1; 

}
Run Code Online (Sandbox Code Playgroud)

这段代码在做什么,它有什么用呢?看起来它正在向该字段添加某种形式的元数据.这是怎么回事?

做一些谷歌我发现这被称为"注释",但所有附加到它上面的东西都超出了我的想象.任何类似于此类事例的例子都将受到赞赏.

Mic*_*tha 5

注释用作"机器可读元数据" - 它们以编译器和运行时可以解析甚至可能理解的方式描述它们标记的字段,方法和类.如果您熟悉.NET的属性,您会发现Java注释的使用方式类似.

例如,示例中TileNetworkData定义的注释本身使用注释进行修饰Retention(RetentionPolicy.RUNTIME).这告诉编译器将TileNetworkData注释嵌入到它注释的字段的字节码中.相同的注释也告诉Java运行时,当它加载带有TileNetworkData注释字段的类时,它应该保留TileNetworkData注释以进行运行时反射.

现在,您的代码可以反映对象的字段以查找TileNetworkData注释,并对带有注释的字段执行某些操作:

// I haven't even compiled this code, and even if it works, it's still insane.
// (others who know annotations better should feel free to edit or replace)
public void copyTileNetworkDataToCache (Object data, Cache<?> cache) {
  for (Field f : data.getClass().getFields()) {
    if (f.isAnnotationPresent(TileNetworkData.class)) {
      cache.save(f.get(data));
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用JDK 5中的前端和JDK 6及更高版本中的开关编写教授Java编译器如何在编译时解释注释的代码.要构成另一个蹩脚的示例,访问磁贴网络可能需要很长时间,以至于您希望尽可能避免使用来自它的数据.因此,您可能希望列出包含TileNetworkData-annotated字段的所有类,因此您可以查看所有类,并可能重写那些不一定需要访问tile网络的类.为此,您可以编写一个打印出所有匹配类的注释处理器,然后在编译时指向处理器.aptjavacapt