首页 > 解决方案 > 如何使用 Java 中的原语避免 NoSuchMethodException

问题描述

我正在处理遗留项目,当我必须使用操作对象制作额外的初始化内容时,我陷入了困境。在这段代码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"当 value 是 Object 类型(String、Integer 等)并且AdmAction实现的 setter 方法使用相同的值时,代码可以正常工作。但是当我有一个问题时,例如Integertype inutilParams和 setter 方法,action其中 consumes int。当然代码抛出NoSuchMethodException

示例:
动作 impl:

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);
        }
    });

我想这对于实际情况来说有点野蛮。任何人都可以帮助我找到编写更好、更美观的代码的方法吗?

标签: javareflection

解决方案


您可以使用java.beans.Statement它,它将进行拆箱。

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

推荐阅读