15

我在 Java 中创建了简单的注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    String columnName();
}

和班级

public class Table {

    @Column(columnName = "id")
    private int colId;

    @Column(columnName = "name")
    private String colName;

    private int noAnnotationHere;

    public Table(int colId, String colName, int noAnnotationHere) {
       this.colId = colId;
       this.colName = colName;
       this.noAnnotationHere = noAnnotationHere;
    }  
}

我需要遍历所有带有注释的字段,Column并获取字段和注释的名称。但是我在获取每个字段的时遇到了问题,因为它们都是不同的数据类型

有什么可以返回具有特定注释的字段集合吗?我设法用这段代码做到了,但我不认为反射是解决它的好方法。

Table table = new Table(1, "test", 2);

for (Field field : table.getClass().getDeclaredFields()) {
    Column col;
    // check if field has annotation
    if ((col = field.getAnnotation(Column.class)) != null) {
        String log = "colname: " + col.columnName() + "\n";
        log += "field name: " + field.getName() + "\n\n";

        // here i don't know how to get value of field, since all get methods
        // are type specific

        System.out.println(log);
    }
}

我是否必须将每个字段包装在对象中,这将实现类似的方法getValue(),还是有更好的方法来解决这个问题?基本上我所需要的只是每个被注释的字段的字符串表示。

编辑:是的field.get(table),但仅适用于public字段,即使对于字段,有什么方法可以做到这一点private吗?还是我必须制作吸气剂并以某种方式调用它?

4

4 回答 4

11

每个对象都应该定义 toString()。(并且您可以为每个类覆盖它以获得更有意义的表示)。

所以你的“//这里我不知道”评论在哪里,你可以有:

Object value = field.get(table);
// gets the value of this field for the instance 'table'

log += "value: " + value + "\n";
// implicitly uses toString for you
// or will put 'null' if the object is null
于 2009-04-10T15:58:52.683 回答
9

反射正是解决它的方法。在执行时找出有关类型及其成员的信息几乎就是反射的定义!你做的方式在我看来很好。

要查找字段的值,请使用field.get(table)

于 2009-04-10T15:59:05.677 回答
4

反射正是查看注释的方式。它们是附加到类或方法的一种“元数据”形式,Java 注释被设计为以这种方式进行检查。

于 2009-04-10T16:00:39.603 回答
2

反射是处理对象的一种方法(如果字段是私有的并且没有任何类型的访问器方法,可能是唯一的方法)。您需要查看Field.setAccessible,也许还有Field.getType

另一种方法是使用编译时注释处理器生成另一个用于枚举带注释字段的类。这需要 Java 5 中的com.sun API,但 Java 6 JDK 的支持更好(Eclipse 等 IDE 可能需要特殊的项目配置)。

于 2009-04-10T16:19:55.753 回答