how to pass multiple parameters to a method in java reflections

前端 未结 4 1556
庸人自扰
庸人自扰 2020-12-30 15:15

Hi i am using reflections to achieve something. I have been given class name, method name of that class and parameter values that needs to be passed to that method in a file

相关标签:
4条回答
  • 2020-12-30 15:24

    Hi all i have found the solution to the above question. below is the sample code snippet.

    package reflections;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class ReflectionTest {
        public void method1(String str, int number) {
            System.out.println(str + number);
        }
    
        public void method1(String str) {
            System.out.println(str);
        }
    
        public void method1() {
            System.out.println("helloworld");
        }
    
        public static void main(String[] args) throws ClassNotFoundException,
                InstantiationException, IllegalAccessException,
                NoSuchMethodException, SecurityException, IllegalArgumentException,
                InvocationTargetException {
            // Step 1) Make an object array and store the parameters that you wish
            // to pass it.
            Object[] obj = {};// for method1()
            // Object[] obj={"hello"}; for method1(String str)
            // Object[] obj={"hello",1}; for method1(String str,int number)
            // Step 2) Create a class array which will hold the signature of the
            // method being called.
            Class<?> params[] = new Class[obj.length];
            for (int i = 0; i < obj.length; i++) {
                if (obj[i] instanceof Integer) {
                    params[i] = Integer.TYPE;
                } else if (obj[i] instanceof String) {
                    params[i] = String.class;
                }
                // you can do additional checks for other data types if you want.
            }
    
            String methoName = "method1"; // methodname to be invoked
            String className = "reflections.ReflectionTest";// Class name
            Class<?> cls = Class.forName(className);
            Object _instance = cls.newInstance();
            Method myMethod = cls.getDeclaredMethod(methoName, params);
            myMethod.invoke(_instance, obj);
        }
    }
    

    I hope this will help others too.

    0 讨论(0)
  • 2020-12-30 15:27

    For two int parameters the example is as below, similarly other datatype parameters can also be called

    Method method=new Test1().getClass().getMethod(x, new Class[] {int.class,int.class});
    

    We can call a method that needs 3 arguments int,int,string as below :

    Method method=new Test1().getClass().getMethod(x, new Class[] {int.class,int.class, String.class});
    
    0 讨论(0)
  • 2020-12-30 15:32
    public class ReflectionSample
    {
        private Object mString = null;
        private int mValue;
    
        public ReflectionSample()
        {
        }
    
        public ReflectionSample(int oValue)
        {
            mValue = oValue;
        }
    
        public ReflectionSample(String oString)
        {
            mString = oString;
        }
    
        public ReflectionSample(String oString, int oValue)
        {
            setValues(oString, oValue);
        }
    
        public void setValues(String oString, int oValue)
        {
            mString = oString;
            mValue = oValue;
        }
    
        public String toString()
        {
            return ""+mString+":"+mValue;
        }
    
        public void run()
        {
            String oInput = "Teststring";
            Class<?> cls;
            String clsname = "main.ReflectionSample";
            Object rs = null;   // ReflectionSample
            Object rsc = null;
    
            System.out.println(this.getClass().getName());
            try
            {
                System.out.println(clsname);
                cls = Class.forName(clsname);
                if(cls == null)
                {
                    System.err.println(clsname + " doesn't exist");
                    return;
                }
    
                // Look for a constructor which has a single string
                Constructor<?> ct = null;
                Class<?>[] param_types = new Class<?>[1];
                Object[] arguments = new Object[1];
    
                param_types[0] = String.class;
    
                // get the string constructor
                ct = cls.getConstructor(param_types);
    
                // We only have one object
                arguments = new Object[1];
                arguments[0] = oInput;
    
                // Instantiate the object with passed in argument.
                rs = ct.newInstance(arguments);
                System.out.println("String constructor sample: "+rs);
    
                // Instantiate with default constructor
                param_types = new Class<?>[0];
                arguments = new Object[0];
                ct = cls.getConstructor(param_types);
                rs = ct.newInstance(arguments);
                rsc = rs; // Keep it for later, to lazy to call it again
                System.out.println("Default constructor sample: "+rs);
    
                // Instantiate with string and int constructor
                param_types = new Class<?>[2];
                arguments = new Object[2];
    
                // Must be in the same order as the params I think
                param_types[0] = String.class;
                param_types[1] = Integer.TYPE;      // <-- Its a primitive so use TYPE not Class
    
                arguments[0] = oInput;
                arguments[1] = new Integer(1);
    
                ct = cls.getConstructor(param_types);
                rs = ct.newInstance(arguments);
                System.out.println("String plus int constructor sample: "+rs);
    
                // call the setValues method
                param_types[0] = String.class;
                param_types[1] = Integer.TYPE;      // <-- Its a primitive so use TYPE not Class
    
                arguments[0] = oInput;
                arguments[1] = 1;
    
                System.out.println("setValues invocation before: "+rsc);
                Method m = cls.getMethod("setValues", param_types);
                m.invoke(rsc, arguments);
                System.out.println("setValues invocation after: "+rsc);
    
                // An alternative method to pass the parameters
                m = cls.getMethod("setValues", String.class, Integer.TYPE);
                m.invoke(rsc, oInput+"x", 2);
                System.out.println("setValues invocation after: "+rsc);
            }
            catch(Throwable e)
            {
                System.err.println(e.getLocalizedMessage());
            }
        }
    }
    

    Output:

    main.ReflectionSample
    main.ReflectionSample
    String constructor sample: Teststring:0
    Default constructor sample: null:0
    String plus int constructor sample: Teststring:1
    setValues invocation before: null:0
    setValues invocation after: Teststring:1
    

    Hope this helps.

    I don't know if this is a newer feature in Java, but I have seen that you can use invoke now with parameters as well, instead of using an array, which might make your code better to read (This is the alternative way). If you need a variable number of arguments and you don't know beforehand how many there will be, allocating the array is defeinitly working and should also be backwardcompatible.

    0 讨论(0)
  • 2020-12-30 15:36

    A simple solution would be to create a Class with the Arguments required to be passed:

    public class ObjectArguments {
      private PrintWriter out;
      private String productId;
      private int action;
    
      public ObjectArguments(PrintWriter out, String productId, int action) {
        this.out = out;
        this.productId = productId;
        this.action = action;
      }
    
      public PrintWriter getOut() {
        return out;
      }
    
      public String getProductId() {
        return productId;
      }
    
      public int getAction() {
        return action;
      }
    }
    

    Assuming that you want to invoke a class Foo with a method named bar.
    Then it would be done like this.

    PrintWriter out = null;
    String productId = null;
    int action = 0;
    
    Class[] paramArguments = new Class[1];  
    paramArguments[0] = ObjectArguments.class;  
    
    ObjectArguments newObj = new ObjectArguments(out,productId,action);
    
    Class cls = Class.forName("Foo");
    Object obj = cls.newInstance();
    
    Method method = cls.getDeclaredMethod("bar", paramArguments);
    method.invoke(obj, newObj);
    
    0 讨论(0)
提交回复
热议问题