Search code examples
javavariablesvariable-types

Getting variable type from variable name in Java


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)

Solution

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