【问题标题】:Get Default Element Value from Annotation in Java从 Java 中的注解中获取默认元素值
【发布时间】:2012-10-30 17:32:03
【问题描述】:

我创建了自己的注释,我通过反射利用它在我的代码中做出决定。注释为其唯一元素设置了默认值。有没有办法通过反射访问默认值?

PageableRequestMapping.java(注解)

package org.tothought.controllers.annotations;

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

@Retention(RetentionPolicy.RUNTIME)
public @interface PageableRequestMapping {
    String variablePath() default "/";
}

获取默认值的伪代码

private int parsePageNumber(StringBuffer requestURL,
        PageableRequestMapping pageableRequestMapping) {

        String variablePath = pageableRequestMapping.variablePath();

    //Psuedo code doesn't work in Java, included to illustrate intentions   
        if(variablePath.equalsIgnoreCase(pageableRequestMapping.variablePath().default())){
           //handle default case    
        }else{
          //handle different case
        }
        return 0;
}

我对这个问题的研究没有发现任何例子。我推测这个值可以通过类以静态方式访问,但它不能。所以我有两个问题。

  • 是否可以在注解中获取元素的默认值?
  • 如果是这样,怎么做?

另外,我知道我可以对这个值进行硬编码,但是我想让程序更健壮一些。

【问题讨论】:

    标签: java reflection annotations


    【解决方案1】:

    可以使用反射获取Method对象,然后使用Method#getDefaultValue()

    Method method = pageableReqMapping.annotationType().getMethod("variablePath");
    String variablePath = (String) method.getDefaultValue();
    

    这是一个具体的例子:

    public class AnnotationTest {
    
      public static void main(String[] args) throws Exception {
        Class<?> clazz = Annotation.class;
        Method method = clazz.getDeclaredMethod("value");
        String value = (String) method.getDefaultValue();
        System.out.println(value);
      }
    
      public @interface Annotation {
        String value() default "default value";
      }
    }
    

    【讨论】:

    • 解决方法是返回null;我正在检查以确保不是我。这段代码是你跑的吗?
    • 我刚刚想通了,你的粘贴再次证实了这一点。您需要以静态方式获取课程。您需要使用PageableRequestMapping.class 而不是pageableRequestMapping.getClass。我想知道为什么从实例中获取类与静态访问类不同。感谢您的出色回答,我很感激。
    • @kmb385 很高兴能帮上忙。我一直在测试这个奇怪的现象,我刚刚找到了原因和解决方案。 getClass(),当在通过Class#getAnnotation(Class) 获取的注解上调用时,实际上是$Proxy1 的一个实例。另一种方法annotationType() 将返回正确的注释类。我正在编辑我的答案以使用它,我建议使用它而不是静态访问该类。 pastie.org/5357208
    • 那么您在网络的哪个阴暗处发现了这些信息,或者它在您的测试中显示出来了?
    • 我打印了getAnnotation(Annotation.class) 的值,即$Proxy1,但为了展示annotationType() 的使用,从测试程序中删除了该值(以及其他调试)。
    【解决方案2】:

    你可以这样做,通过在一个类上应用你的注释并通过反射从类中检索它:

    @PageableRequestMapping
    class MyUtilClass{
    }
    
    
    public String getDefaultValue(){
        PageableRequestMapping pageableRequestMapping = MyUtilClass.class.getAnnotation(PageableRequestMapping.class);
        return pageableRequestMapping.variablePath();
    }
    

    【讨论】:

    • OP 询问如何获取注解的默认值,即/,而不是test
    • 我知道,这就是我要说的所有方法,而且它有效,因此绝对不需要标记它。
    • 在您编辑它之前,我对它投了反对票,因为它不能正常工作。尽管现在可以使用,但它不是太健壮。 OP 提到他可以将值存储在一个常量中(如MAPPING_DEFAULT),然后简单地访问该值。可以说,您的解决方案需要比常数更不受欢迎的混乱。
    • 是的,完全同意@Vulcan,不否认,我更喜欢你的方法,但只是提供一种替代方法 - 我已经 +1 了你的答案
    • 这种方法很有用,因为您需要检索更多注释方法的默认值,因为您可以通过单个对象而不是检查已定义的常量。此外,即使您定义了一个包含默认值的常量,您也不能将其作为默认值分配给注释,这意味着如果有人不记得同时更新常量和注释,将来可能会出现代码更新错误。
    猜你喜欢
    • 2010-10-23
    • 2011-03-16
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多