【问题标题】:Map<String, methodReference> - Run methodReference with argumentsMap<String, methodReference> - 使用参数运行 methodReference
【发布时间】:2019-09-05 09:23:03
【问题描述】:

我尝试过运行这样的方法,但没有成功。

我的地图与方法参考:

private final Map<String, Runnable> validationMethods = new HashMap<>();

{
  validationMethods.put("getTransactions", ValidationInterceptor::validateTransactions);
  validationMethods.put("getDeals", ValidationInterceptor::validateDeals);
}

这是我尝试从地图运行的方法:

private static void validateTransactions(Method method, List<Object> arguments, Object resourceInstance) {
    doSomthing(method, arguments, resourceInstance);
}

private static void validateDeals(Method method, List<Object> arguments, Object resourceInstance) {
    doSomthing(method, arguments, resourceInstance);
}

以及带参数的核心方法:

protected void handleValidation(final Message message, final Method method, final List<Object> arguments) {
    validationMethods.get(method.getName()).run();
}

问题是 - 如何将参数传递给静态方法?

【问题讨论】:

  • 您的Map 值为Runnable,并且由于run() 不带参数,因此您无法为其分配带参数的方法引用。

标签: java java-8 method-reference


【解决方案1】:

定义a functional interface

@FunctionalInterface
interface Validator {
    void validate(Method method, List<Object> arguments, Object resourceInstance);
}

将地图类型改为:

private final Map<String, Validator> validationMethods = new HashMap<>();

在从地图中检索到的Validator 上调用方法validate

validationMethods.get(method.getName()).validate(method, arguments, message);

问题是您的静态方法不能表示为Runnables:方法run 没有参数(当您调用.run() 时您不传递参数)。

在标准库中,我们没有一个可以接受 3 个参数并返回一个值的函数。如果您将参数数量减少到 2 个,我们可以使用 BiFunction。如果有一个参数,Function 会派上用场。这就是为什么在这里声明自己的函数式接口是合理的。

【讨论】:

    【解决方案2】:

    我可以看到您使用Method 来定义所需的验证规则。所以你应该有一个带有所需方法和参数数量的接口:

    @FunctionalInterface 接口验证规则 {

    // add as many parameters as you need
    void validate(Message message, List<Object> arguments);
    

    }

    那么最好将每个验证封装在单独的类中。它可以帮助您测试和支持它们中的每一个:

    public final class GetTransactionsValidationRule implements ValidationRule {
    
        @Override
        public void validate(Message message, List<Object> arguments) {
            // logic validation
        }
    }
    
    public final class GetDealsValidationRule implements ValidationRule {
    
        @Override
        public void validate(Message message, List<Object> arguments) {
            // logic validation
        }
    }
    

    最后应该将基本的验证逻辑封装在另一个类中:

    public class ValidationService {
    
        private static final ValidationRule NULL = (message, arguments) -> {};
    
        private final Map<String, ValidationRule> rules = new HashMap<>();
    
        {
            rules.put("getTransactions", new GetTransactionsValidationRule());
            rules.put("getDeals", new GetDealsValidationRule());
        }
    
        public void handleValidation(Message message, Method method, List<Object> arguments) {
            rules.getOrDefault(method.getName()).validate(arguments);
        }
    
    }
    

    您现在只需要创建一个ValidationService 的实例并调用handleValidation 方法:

    ValidationService validationService = new ValidationService();
    validationService.handleValidation(...);
    

    【讨论】:

      猜你喜欢
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      • 2023-04-01
      • 2011-03-02
      • 2017-07-13
      • 2018-01-06
      相关资源
      最近更新 更多