0

I want to call several "setter" methods dynamically from several values passed. Each method will have String, int... type of variables to set (for example: setUserName(String userName) or setUserAge(int age)).

In my case I have a setter method "setUse_status(int use_status)" and I´m not able to configure the getDeclaredMethod method to work. It seems that when getting the method the classVariableName is set to a String (obvious as I´m passing that variable as a name [string] of the variable).

I´m figuring out how to obtain the variable type and set it in the getDeclaredMethod call.

So, I have this code:

private void  getValueFromColumn(Object paramsClass, String classVariableName, Object dataBaseValue) {

//First create the string with the method name
    String methodName = "set" + classVariableName.substring(0, 1).toUpperCase().toString() +
            classVariableName.substring(1);

    Method loadParamsMethod;


    try {
        loadParamsMethod = paramsClass.getClass().getDeclaredMethod(methodName, classVariableName.getClass());

        try {
            loadParamsMethod.invoke(paramsClass, dataBaseValue);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {

            e.printStackTrace();
        }
    } catch (NoSuchMethodException | SecurityException e) {

        e.printStackTrace();
    }
}

And the error:

java.lang.NoSuchMethodException: com.sener.dbgui.model.params.CommonParameters.setUse_status(java.lang.String)
at java.base/java.lang.Class.getDeclaredMethod(Class.java:2432)
at com.sener.dbgui.utils.ParamsClassUtils.getValueFromColumn(ParamsClassUtils.java:72)
at com.sener.dbgui.utils.ParamsClassUtils.retrieveParamsData(ParamsClassUtils.java:107)
at com.sener.dbgui.utils.ParamsClassUtils.loadAllParameters(ParamsClassUtils.java:39)
at com.sener.dbgui.controller.ComponentController.retrieveParamsFromDB(ComponentController.java:506)
at com.sener.dbgui.controller.ComponentController.access$18(ComponentController.java:494)
at com.sener.dbgui.controller.ComponentController$4.run(ComponentController.java:294)
at java.base/java.lang.Thread.run(Thread.java:844)
18
  • Can you give an example for classVariableName? Would it be "int" or "use_status" in your example? Commented Feb 20, 2018 at 8:59
  • Ok, I have seen this possible solution link Commented Feb 20, 2018 at 8:59
  • 2
    classVariableName.getClass() will return String - should be obvious. Dou you mean dataBaseValue.getClass() instead? In that case be aware that int isn't a class, i.e. when you pass an integer as dataBaseValue you'd get a wrapper class, e.g. Integer and getDeclaredMethod(name, Integer.class) won't find the method if it accepts an int parameter. Commented Feb 20, 2018 at 8:59
  • Yes, it would be use_status in my example Commented Feb 20, 2018 at 8:59
  • 1
    But, as I have the variable name and class, is there a way I can find the variable type of the setter method? From my complete ignorance this should be simple... Commented Feb 20, 2018 at 9:13

1 Answer 1

1

The problem with your code is that you are using classVariableName.getClass() as parameter type when looking for the method. Since classVariableName is String, classVariableName.getClass() always gives you a string. You should use something like dataBaseValue.getClass() instead, but also consider the case with primitive/wrapper types. Like, you get Integer but your setter accepts int.

You cannot find out the type of the method parameter by name just from classVariableName, it is not that easy. What you could (theoretically) do:

  • Get all the declared methods using Class.getDeclaredMethods().
  • Search for methods with the corresponding name (there may be several).
  • For each of the methods, discover the parameter names (more on it below).
  • Select the method with the corresponding parameter name.

As for "discover the parameter names", see this answer:

Getting the name of a method parameter

It is not always possible: the code must be compiled with debug information.

Finally, why do you want to deal with parameter names anyway? Setter convention per se is string enough, there is actually no need to check parameter names, but it makes stuff much more complicated. Just search for a method with corresponding name and signature and that's it.

Sign up to request clarification or add additional context in comments.

9 Comments

Nonetheless, using this approach I will still have the primitive/wrapper types issue, won´t I? For example, having a setter for a float type variable will not work. Is this correct?
@user6127833 Yes, you have to solve primitive/wrapper type anyway. I'd check Apache Commons (probably Lang) libraries to see if they have some utility classes for this.
Any suggestion on this?
@user6127833 None except for - just implement it! It is not so difficult.
Sorry but i´m still new to this and I´m a bit lost when trying to find a way. Is there an easy example of something similar to what I have to do? Maybe this link is an approach.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.