【问题标题】:Java - Get arguments passed to a method?Java - 获取传递给方法的参数?
【发布时间】:2012-12-12 15:38:16
【问题描述】:

是否可以使用反射 api 将参数传递给 Java 中的方法?

是否可以使用 AOP 库(如 AspectJ)来实现这一点?

我在 Android 上运行。

public abstract class Base {

   public void printArguments() {

      //Here I need to get access to arg1, arg2, arg3
   }

}

.

public class MyClass extends Base {

   public void (String arg1, Integer arg2, String arg3) {

      super.printArguments();      
   }
}

【问题讨论】:

标签: java reflection aop


【解决方案1】:

是否有可能使用 AOP 库如 AspectJ 来实现这一点?

是的,当然。这是 AspectJ 中典型的初学者练习,如下所示:

public class SampleClass {
    public SampleClass() { super(); }
    public SampleClass(String s) { this(); }
    public SampleClass(int i) { this(); }
    public void method01(String s, Number n, Throwable t) {}
    public void method02(int i, String s, double d) {}
    public void method03(String s) {}
    public void method04() {}
    public void method05(String s, Number n, double d) {}

    public static void main(String[] args) {
        new SampleClass().method01("foo", new Integer(11), new RuntimeException("error"));
        new SampleClass("test").method02(11, "bar", Math.PI);
        new SampleClass(123).method03("zot");
        new SampleClass("another test").method04();
        new SampleClass(456).method05("baz", new Integer(11), Math.E);
    }
}

现在你只需要编写一个切面来拦截你所有的方法执行(以及可选的构造函数执行,如下所示):

public aspect MethodArgsAspect {
    pointcut allMethods()      : execution(* *(..));
    pointcut allConstructors() : execution(*.new(..));

    before() : !within(MethodArgsAspect) && (allMethods() || allConstructors()) {
        System.out.println(thisJoinPointStaticPart.getSignature());
        for (Object arg : thisJoinPoint.getArgs())
            System.out.println("    " + arg);
    }
}

运行SampleClass.main时,会打印这个方面:

void SampleClass.main(String[])
    [Ljava.lang.String;@7fdcde
SampleClass()
void SampleClass.method01(String, Number, Throwable)
    foo
    11
    java.lang.RuntimeException: error
SampleClass()
SampleClass(String)
    test
void SampleClass.method02(int, String, double)
    11
    bar
    3.141592653589793
SampleClass()
SampleClass(int)
    123
void SampleClass.method03(String)
    zot
SampleClass()
SampleClass(String)
    another test
void SampleClass.method04()
SampleClass()
SampleClass(int)
    456
void SampleClass.method05(String, Number, double)
    baz
    11
    2.718281828459045

【讨论】:

  • 它会拦截程序的所有方法。有什么办法可以动态地做到这一点,而应用程序正在运行并且需要识别正在传递的方法参数值?
  • 如果(a)您创建一个新问题而不是劫持这个问题,我将很乐意回答您的问题,因为您想要的东西与此处提出和回答的内容不同,并且(b)您提出问题以我能理解的方式,还提供了说明性的示例代码(如果可能,可以执行),所以我有一些东西要为你实际修复或实现。您可以在此处的另一条评论中添加指向新问题的链接,以便我找到它。非常感谢。
【解决方案2】:

你可以用 java 变量参数 来实现这个逻辑

因为我不确定它是否可以在反射中完成

我会做这个选择

www.java.net/pub/a/today/2004/04/19/varargs.html

你的方法在哪里

 public void printArguments(Obeject... argArr) {

  //Here I need to get access to arg1, arg2, arg3
  //TODO iterate over object array (ie: argArr) and print it.
  }

在你的子类中

public void someMethodName(String arg1, Integer arg2, String arg3) {

  super.printArguments(arg1,arg2);   
  super.printArguments(arg1,arg2,arg3);      //the print argument can be called with any number of argument
}

【讨论】:

  • 我不喜欢这样做,我宁愿让一切都自动化,但如果我不能让某种方法拦截起作用,我可能会这样做。谢谢
猜你喜欢
  • 2011-06-24
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多