Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.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_Reflection_Parameters_Annotations_Arguments - Fatal编程技术网

如何在Java中通过反射获取方法参数的值?

如何在Java中通过反射获取方法参数的值?,java,reflection,parameters,annotations,arguments,Java,Reflection,Parameters,Annotations,Arguments,考虑以下代码: public void example(String s, int i, @Foo Bar bar) { /* ... */ } 我对用@Foo注释的参数的值感兴趣。假设我已经通过反射(使用方法#getParameterAnnotations())计算出哪个方法参数具有@Foo注释。(我知道这是参数列表中的第三个参数。) 现在如何检索条的值以供进一步使用?您不能。反射无法访问局部变量,包括方法参数 如果需要该功能,则需要拦截方法调用,可以通过以下几种方式之一执行此操作:

考虑以下代码:

public void example(String s, int i, @Foo Bar bar) {
    /* ... */
}
我对用
@Foo
注释的参数的值感兴趣。假设我已经通过反射(使用
方法#getParameterAnnotations()
)计算出哪个方法参数具有
@Foo
注释。(我知道这是参数列表中的第三个参数。)


现在如何检索
条的值以供进一步使用?

您不能。反射无法访问局部变量,包括方法参数

如果需要该功能,则需要拦截方法调用,可以通过以下几种方式之一执行此操作:

  • AOP(AspectJ/Spring AOP等)
  • 代理(JDK、CGLib等)
在所有这些中,您将从方法调用中收集参数,然后告诉方法调用执行。但无法通过反射获得方法参数

更新:下面是一个示例方面,让您开始使用AspectJ中基于注释的验证

public aspect ValidationAspect {

    pointcut serviceMethodCall() : execution(public * com.yourcompany.**.*(..));

    Object around(final Object[] args) : serviceMethodCall() && args(args){
        Signature signature = thisJoinPointStaticPart.getSignature();
        if(signature instanceof MethodSignature){
            MethodSignature ms = (MethodSignature) signature;
            Method method = ms.getMethod();
            Annotation[][] parameterAnnotations = 
                method.getParameterAnnotations();
            String[] parameterNames = ms.getParameterNames();
            for(int i = 0; i < parameterAnnotations.length; i++){
                Annotation[] annotations = parameterAnnotations[i];
                validateParameter(parameterNames[i], args[i],annotations);
            }
        }
        return proceed(args);
    }

    private void validateParameter(String paramName, Object object,
        Annotation[] annotations){

        // validate object against the annotations
        // throw a RuntimeException if validation fails
    }

}
公共方面验证spect{
切入点serviceMethodCall():执行(public*com.yourcompany.**(..);
对象(最终对象[]args):serviceMethodCall()&&args(args){
签名签名=thisJoinPointStaticPart.getSignature();
if(签名实例of MethodSignature){
MethodSignature ms=(MethodSignature)签名;
Method=ms.getMethod();
注释[][]参数注释=
方法。getParameterAnnotations();
字符串[]parameterNames=ms.getParameterNames();
for(int i=0;i
我不明白这个问题。
bar
的值仅在运行时可用。是否要拦截对
示例
的调用?或者你是指数据类型
Bar
?我已经在使用AspectJ了,但还没有找到一种方法。这是前面的问题:@soc好的,先看我的更新,买来真正学会如何做(或者在《嘿,谢谢!》上提问:-)我已经买了这本书,但我试图把所有东西都放进匹配签名中,但没有用…@soc我知道。在方法参数的可变数量的注释上匹配注释是行不通的。Edit:mhh,这个示例是否也适用于注释语法?我找不到适用于
thisJoinPointStaticPart
的导入。