Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Get arguments passed to a method?

Is it possible to get arguments pass to a method in Java using reflection api?

Is it possible to achieve this using AOP libraries like AspectJ?

I am running on 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();      
   }
}
like image 546
aryaxt Avatar asked Oct 06 '22 12:10

aryaxt


2 Answers

Is it possible to achieve this using AOP libraries like AspectJ?

Yeah, sure. This is kind of the typical beginner's exercise in AspectJ, like so:

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);
    }
}

Now you just need to write an aspect which intercepts all your method executions (and optionally also constructor executions, as shown below):

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);
    }
}

When running SampleClass.main, this aspect will print:

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
like image 50
kriegaex Avatar answered Oct 10 '22 03:10

kriegaex


You could you the java variable argument for attaining this logic

since i am not sure if it can be done in reflection

i would have done this alternative

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

where your method

 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.
  }

and in your sub class

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
}
like image 28
Naveen Babu Avatar answered Oct 10 '22 02:10

Naveen Babu