【问题标题】:Passing getter/setter as a method reference [duplicate]将getter/setter作为方法引用传递[重复]
【发布时间】:2025-12-17 21:25:03
【问题描述】:

我有一堆这样的条目:

        if (update) {
            if (activity.getName() == null) {
                logger.debug("      Setting name on " + id);
            } else
            if (!activity.getName().equals(name)) {
                logger.debug("      Updating name on " + id);
            }
        }
        // if (!update) not logged on purpose
        activity.setName(name);

        if (update) {
            if (activity.getPlannedDuration() == null) {
                logger.debug("      Setting plannedDuration on " + id);
            } else
            if (!activity.getPlannedDuration().equals(duration)) {
                logger.debug("      Updating plannedDuration on " + id);
            }
        }
        // if (!update) not logged on purpose
        activity.setPlannedDuration(duration);

出于代码可读性的目的,我想将它们替换为以下内容:

        updateField(update, name, "name", activity.getName, activity.setName);
        updateField(update, duration, "plannedDuration", activity.getPlannedDuration, activity.setPlannedDuration);

我知道这是一个常见问题,我做了功课,wraping methods to Callable interface 似乎是最简单的解决方案。但是,该解决方案将比我当前的代码更加混乱(请记住,我这样做是为了便于阅读)。

那么,对于我在 Java 中遇到的问题,是否有一个优雅的解决方案?

【问题讨论】:

    标签: java function-pointers


    【解决方案1】:

    您可以将特定代码重构为:

    logUpdate(update, activity.getName(), name, "name", id);
    activity.setName(name);
    
    logUpdate(update, activity.getPlannedDuration(), plannedDuration,
              "planned duration", id);
    activity.setPlannedDuration(plannedDuration);
    
    ...
    
    static void logUpdate(boolean update, Object currentValue,
                          Object newValue, String field, String id) {
        if (currentValue == null) {
            logger.debug("      Setting " + field + " on " + id);
        } else if (!currentValue.equals(newValue)) {
            logger.debug("      Updating name on " + id);
        }    
    }
    

    这不是精彩,但它仍然是一个改进。请注意,无论您是否记录了该字段,目前您实际上都在更新该字段 - 您确定这是您的意图吗?我更期待这样的事情:

    if (update) {
        logUpdate(activity.getName(), name, "name", id);
        activity.setName(name);
    
        logUpdate(activity.getPlannedDuration(), plannedDuration,
                 "planned duration", id);
        activity.setPlannedDuration(plannedDuration);
    }
    

    但是不,目前在 Java 中没有简单的方法来传递方法。然而,Java 8 将通过方法引用和 lambda 表达式使其变得更加简单。

    【讨论】:

    • 是的,我知道我没有记录所有选项,我在我的代码中添加了一个说明。我考虑过将日志记录和设置分开,但我想我会先在这里要求一个完整的解决方案。无论如何,感谢您的洞察力!
    • @dijxtra:不,你错过了我的意思。即使update 为假,您也在更新对象(调用setName)。这肯定不合适。
    • 是的,这是合适的。如果 update 为 false,那只意味着我没有更新现有活动的字段,而是完全创建一个新活动(之前已写入日志),因此很明显需要调用所有这些设置器。因此,无需记录。
    最近更新 更多