从 Java 中的变量名获取变量类型
Getting variable type from variable name in Java
我想根据传递的多个值动态调用多个 "setter" 方法。
每个方法都会有 String, int... 类型的变量来设置(例如:setUserName(String userName) 或 setUserAge(int age))。
在我的例子中,我有一个 setter 方法 "setUse_status(int use_status)" 并且我无法配置 getDeclaredMethod 方法来工作。
似乎在获取方法时,classVariableName 设置为字符串(很明显,因为我将该变量作为变量的名称 [string] 传递)。
我正在弄清楚如何获取变量类型并在 getDeclaredMethod 调用中设置它。
所以,我有这个代码:
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();
}
}
错误:
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(ComponentController.java:494)
at com.sener.dbgui.controller.ComponentController.run(ComponentController.java:294)
at java.base/java.lang.Thread.run(Thread.java:844)
您的代码存在问题,您在查找方法时使用 classVariableName.getClass()
作为参数类型。因为 classVariableName
是 String
,所以 classVariableName.getClass()
总是给你一个字符串。您应该改用 dataBaseValue.getClass()
之类的东西,但也要考虑 primitive/wrapper 类型的情况。比如,你得到 Integer
但你的 setter 接受 int
.
仅仅从classVariableName
中是无法通过名字查出方法参数的类型的,不是那么容易的。你可以(理论上)做什么:
- 使用
Class.getDeclaredMethods()
获取所有声明的方法。
- 搜索具有相应名称的方法(可能有多个)。
- 对于每个方法,找出参数名称(更多内容见下文)。
- Select对应参数名的方法
至于"discover the parameter names",看这个回答:
Getting the name of a method parameter
并非总是可行:必须使用调试信息编译代码。
最后,你为什么要处理参数名称呢? Setter 约定本身就足够了,实际上不需要检查参数名称,但它使事情变得更加复杂。只需搜索具有相应名称和签名的方法即可。
我想根据传递的多个值动态调用多个 "setter" 方法。 每个方法都会有 String, int... 类型的变量来设置(例如:setUserName(String userName) 或 setUserAge(int age))。
在我的例子中,我有一个 setter 方法 "setUse_status(int use_status)" 并且我无法配置 getDeclaredMethod 方法来工作。 似乎在获取方法时,classVariableName 设置为字符串(很明显,因为我将该变量作为变量的名称 [string] 传递)。
我正在弄清楚如何获取变量类型并在 getDeclaredMethod 调用中设置它。
所以,我有这个代码:
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();
}
}
错误:
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(ComponentController.java:494)
at com.sener.dbgui.controller.ComponentController.run(ComponentController.java:294)
at java.base/java.lang.Thread.run(Thread.java:844)
您的代码存在问题,您在查找方法时使用 classVariableName.getClass()
作为参数类型。因为 classVariableName
是 String
,所以 classVariableName.getClass()
总是给你一个字符串。您应该改用 dataBaseValue.getClass()
之类的东西,但也要考虑 primitive/wrapper 类型的情况。比如,你得到 Integer
但你的 setter 接受 int
.
仅仅从classVariableName
中是无法通过名字查出方法参数的类型的,不是那么容易的。你可以(理论上)做什么:
- 使用
Class.getDeclaredMethods()
获取所有声明的方法。 - 搜索具有相应名称的方法(可能有多个)。
- 对于每个方法,找出参数名称(更多内容见下文)。
- Select对应参数名的方法
至于"discover the parameter names",看这个回答:
Getting the name of a method parameter
并非总是可行:必须使用调试信息编译代码。
最后,你为什么要处理参数名称呢? Setter 约定本身就足够了,实际上不需要检查参数名称,但它使事情变得更加复杂。只需搜索具有相应名称和签名的方法即可。