Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检索Java注释属性_Java_Annotations - Fatal编程技术网

检索Java注释属性

检索Java注释属性,java,annotations,Java,Annotations,如何在带注释的方法上检索注释的值 我有: @myAnnotation(attribute1 = value1, attibute2 = value2) public void myMethod() { //I want to get value1 here } 获取实例 获取注释 获取注释属性值 比如: Method m = getClass().getMethod("myMethod"); MyAnnotation a = m.getAnnotation(MyAnnotation.cla

如何在带注释的方法上检索注释的值

我有:

@myAnnotation(attribute1 = value1, attibute2 = value2)
public void myMethod()
{
  //I want to get value1 here
}
  • 获取实例
  • 获取注释
  • 获取注释属性值
  • 比如:

    Method m = getClass().getMethod("myMethod");
    MyAnnotation a = m.getAnnotation(MyAnnotation.class);
    MyValueType value1 = a.attribute1();
    
    当然,您需要捕获/处理适当的异常。以上假设您确实正在从当前类中检索方法(将
    getClass()
    替换为
    class.forName()
    否则),并且所讨论的方法是公共的(如果不是这样,请使用
    getDeclaredMethods()

    两件重要的事情:

    • 无法获取当前方法,例如,没有诸如getClass()之类的getMethod()。因此,访问自己注释的方法需要知道自己的名称
    • 批注的保留策略必须设置为
      运行时
      ,以便您可以在运行时访问批注。默认值是编译时,这意味着注释在类文件中可用,但不能在运行时使用反射进行访问
    完整示例:

    @Retention(RetentionPolicy.RUNTIME)
    public static @interface MyAnnotation {
        String value1();
    
        int value2();
    }
    
    @Test
    @MyAnnotation(value1 = "Foo", value2 = 1337)
    public void testAnnotation() throws Exception {
        Method[] methods = getClass().getMethods();
        Method method = methods[0];
        assertEquals("testAnnotation", method.getName());
        MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
        assertEquals("Foo", annotation.value1());
        assertEquals(1337, annotation.value2());
    }
    

    @姆哈勒:在你的帖子上评论有点太长了。显然,需要进一步细化以处理重载方法,但这并非不可能

    import java.lang.reflect.Method;
    
    public class Hack {
        public static void main (String[] args) {
            (new Hack()).foobar();
        }
        public void foobar () {
            Method here = getCurrentMethod(this);
            System.out.format("And here we are: %s\n", here);
        }
        public static final Method getCurrentMethod(Object o) {
            String s = Thread.currentThread().getStackTrace()[2].getMethodName();
            Method cm = null;
            for(Method m : o.getClass().getMethods()){
                if(m.getName().equals(s)){
                    cm = m; break;
                }
            }
            return cm;
        }
    }
    

    [编辑:感谢Alexandr Priymak在main()中发现了错误]

    要获取当前方法,请尝试使用以下代码:

    Thread.currentThread().getStackTrace()[1].getClassName().toString()+\".\"+Thread.currentThread().getStackTrace()[1].getMethodName().toString()
    

    你能提供你想要完成的更多细节吗?正如我所说的,我想使用attribute1的值,而不必在代码上重复它,这不是一种真正有效的编程方法。与在代码内部的最终变量中设置值或在方法外部的最终静态变量中设置值相比,在注释中设置值没有任何好处。关于步骤1,它不应该是“MyValueType value1=a.getAttribute1();”吗,使用以下解决方案获取方法实例:请注意,方法名称可能会因模糊处理或编译器特定的优化而更改,最终无法保证在运行时被名称引用。有一种方法可以获取当前方法。
    Thread.currentThread().getStackTrace()[2].getMethodName()
    new Throwable().fillInStackTrace().getStackTrace()[0].getMethodName()
    都应该这样做。@ChssPly76,构建stacktrace并不完全可靠,正如javadocs提到的:“在某些情况下,某些虚拟机可能会从堆栈跟踪中忽略一个或多个堆栈帧。在极端情况下,允许没有堆栈跟踪信息的虚拟机[…]从此方法返回零长度数组。“使用以下解决方案获得方法实例:我有一种感觉,如果你真的在生产代码中这样做,它会召唤伟大的老家伙吞噬你的灵魂@跳过头部-为什么?这里有两件事需要注意:(1)数组索引在理论上可能不同于某些JVM上的2,但通过遍历整个跟踪很容易解决;(2) 这对重载方法不起作用;您可以使用javassist执行一些黑魔法,根据行号猜出正确的一个,但这确实有点不确定。不过,除此之外,它工作得非常完美——你认为堆栈跟踪是如何工作的?@chsply76:无需遍历整个跟踪。跟踪方法从顶部开始,一直走到找到自己为止。调用者是下一个。@alphazero-你会这么认为,但不是:-)也就是说,通常情况下是这样,但它没有在任何地方指定,这意味着你可以有一个行为不同的JVM实现(例如,所讨论的方法可能在堆栈跟踪数组的第二个甚至第一个参数中)