【问题标题】:How to inject a map of key-value pairs into an Object with just Core Java?如何仅使用 Core Java 将键值对映射注入到对象中?
【发布时间】:2020-01-15 05:10:03
【问题描述】:

如何仅使用 Core Java 将地图注入到对象中?

我有一个包含 4 个键值(字符串,对象)对的映射和一个包含 3 个字段的类,我想根据键名调用 setter 方法并设置它们。

{
 "variableA": "A",
 "variableB": true,
 "variableC": 1,
 "variableD": "DONT USE"
}

public Class Example {
  public void setVaraibleA(String variableA);
  public void setVaraibleB(Boolean variableB);
  public void setVaraibleC(Integer variableC);
}

Example example = new Example();
// Do something to map it
assert(example.getVariableA.equals("A"));
assert(example.getVariableB.equals(true));
assert(example.getVariableC.equals(1));

【问题讨论】:

    标签: java dependency-injection


    【解决方案1】:

    您可以使用 Java 反射来获取一个方法(给定它的名称)并使用给定的参数调用它。

    Example example = new Example();
    Method method = Example.class.getMethod("setVariableA", String.class);
    
    method.invoke(example, "parameter-value1");
    

    【讨论】:

    • 感谢您的回复!这解决了我的部分问题。有没有办法可以 1. 自动为所有 setter 方法创建 Method 对象,而不用硬编码字段名称? 2.通过知道键名"variable-a",自动使用variableAMethod.invoke(example, "variable-a-value")?
    • 当然,我认为您可以只构建方法名称,即String methodName = "set" + map.getKey()
    【解决方案2】:

    作为@BeppeC 的答案的替代方案,如果您无法轻松确定在运行时注入的对象的类型,并且假设您没有重复的属性名称,我将使用Class's getMethods() 方法和@ 987654322@方法。

    基本上,我会编写如下代码:

    Method[] exampleMethods = Example.class.getMethods();
    Map<String, Method> setterMethodsByPropertyName = new HashMap<>(exampleMethods.length);
    for (Method exampleMethod : exampleMethods) {
      String methodName = exampleMethod.getName();
      if (!methodName.startsWith("set")) {
        continue;
      }
      // substring starting right after "set"
      String variableName = methodName.substring(3);
      // use lowercase here because:
      // 1. JSON property starts with lower case but setter name after "set" starts with upper case
      // 2. property names should all be different so no name conflict (assumption)
      String lcVariableNmae = variableName.toLowerCase();
      setterMethodsByPropertyName.put(lcVariableName, exampleMethod);
    }
    
    // later in the code, and assuming that your JSON map is accessible via a Java Map
    for (Map.Entry<String, ?> entry : jsonMap.entrySet()) {
      String propertyName = entry.getKey();
      String lcPropertyName = propertyName.toLowerCase();
      if(!setterMethodsByPropertyName.containsKey(lcPropertyName)) {
        // do something for this error condition where the property setter can't be found
      }
      Object propertyValue = entry.getValue();
      Method setter = setterMethodsByPropertyName.get(lcPropertyName);
      setter.invoke(myExampleInstance, propertyValue);
    }
    

    【讨论】:

      猜你喜欢
      • 2013-05-04
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      • 2012-07-18
      相关资源
      最近更新 更多