5

我有一个自定义注释,我想在运行时使用它来显示对象属性。我希望它们以源代码顺序出现,但反射不保证Class.getMethods().

有没有办法通过反射或注释处理来按源顺序获取方法(如果涉及多级继承,至少每个类)?

例如,假设我有一个界面Property

package test;

public @interface Property {
    public String name();
}

以及使用该注释的类

package test;

public class MyObject {
    @Property(name = "First")
    public void getFirst() {}

    @Property(name = "Another")
    public void getAnother() {}
}

我想在属性“另一个”之前可靠地获得属性“第一”。

我知道我可以向我的注释添加一个排序属性并对其进行排序,但是如果需要,我有很多类需要更新,所以我正在寻找一种通用方法来实现这一点,而无需修改单个注释。

4

2 回答 2

3

除非您愿意并且能够更改原始源以通过附加注释或现有注释的属性强加顺序,否则这似乎无法通过反射实现。

但是,在注释处理期间是可能的。]的文档表明TypeElement.getEnclosedElements()

包含的元素列表将按有关类型的原始信息源的自然顺序返回。例如,如果有关类型的信息来自源文件,则元素将按源代码顺序返回[强调添加]。

要使其在运行时可用,您需要使用注释处理方法并将其存储在运行时可访问的位置(例如生成的资源文件)。

于 2013-12-02T18:50:11.423 回答
2

如果您将注释收集到 aList<Property>中,您可以List使用Collections.sort(collection, comparator). 主要问题是注释的排序方式没有自然顺序,因此您需要定义此顺序。我已经通过List比较器中使用的 a 定义了顺序。

public class MyObject {

    @Property(name = "First")
    public void getFirst() {
    }

    @Property(name = "Another")
    public void getAnother() {
    }

    @Property(name = "Last")
    public void getLast() {
    }

    public static void main(String[] args) {
        Method[] methods = MyObject.class.getDeclaredMethods();
        List<Property> properties = new ArrayList<Property>();

        for(Method method: methods){
            if(method.isAnnotationPresent(Property.class)){
                properties.add(method.getAnnotation(Property.class));
            }
        }

        for(Property property:properties){
            System.out.println(property.name());
        }

        Collections.sort(properties, new Comparator<Property>(){

            List<String> order = Arrays.asList("Last", "First", "Another");

            @Override
            public int compare(Property arg0, Property arg1) {
              //Compare only considers the sign of result.  
              return (order.indexOf(arg0.name()) - order.indexOf(arg1.name()));
            }

        });

        for(Property property:properties){
            System.out.println(property.name());
        }

    }
}
于 2013-11-27T18:09:25.367 回答