如何使用Java中的原语避免NoSuchMethodException

时间:2018-07-26 14:18:00

标签: java reflection

我正在处理遗留项目,当我不得不使用动作对象制作其他初始化内容时,我陷入了困境。在这段代码中,AdmAction是一个基本接口,在内部方法中,我可以实现其中的任何一个。一些实现要求附加属性,必须使用utilParams中的值来初始化。

private void initActionParams(AdmAction action, Map<String, Object> utilParams) {
    if (utilParams == null) {
      return;
    }
    utilParams.forEach((paramName, value) -> {
        try {
          Method setterMethod = action.getClass().getMethod(setterFor(paramName), value.getClass());
          setterMethod.invoke(action, value);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
          log.error(e.getMessage(), e);
          throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
        }
   });
}

utilParams看起来像"serviceId": 10中的"ticketId": "8a30f5a7-809c-4551-8833-c2a60e4c6fd9"。 当值是对象类型(字符串,整数等)并且AdmAction实现的setter方法使用相同的值时,代码可以正常工作。 但是,例如当我在Integer中键入utilParams并在action中使用setter方法(消耗int)时,就会出现一个问题。 当然,代码会抛出NoSuchMethodException

示例:
动作提示:

public class Foo implements AdmAction {
    // ...
    public void setServiceId(int serviceId) {
        this.serviceId = serviceId;
    }
}

引起异常。

我试图通过方法搜索来改进代码:

private void initActionParams(AdmAction action, Map<String, Object> utilParams) {
    if (utilParams == null) {
      return;
    }
    utilParams.forEach((paramName, value) -> {
        try {
            Method setterMethod = Arrays.stream(action.getClass().getDeclaredMethods())
                .filter((Method method) -> method.getName().equals(setterFor(paramName)))
                .findFirst()
                .orElseThrow(NoSuchMethodException::new);
            setterMethod.invoke(action, value);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            log.error(e.getMessage(), e);
            throw new WebApplicationException(e, Response.Status.BAD_REQUEST);
        }
    });

我想实际情况有些粗鲁。 有人可以帮助我找到编写更好,更美观的代码的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以为此使用java.beans.Statement,这将取消装箱。

java.beans.Statement(action, setterFor(paramName), new Object[] {value})
    .execute();