Passing getter/setter as a method reference

I have a bunch of entries like these two:

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

and for code readability purposes I'd like to replace them with something like this:

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

I'm aware this is a common question, I did my homework, and wraping methods to Callable interface seems to be the simplest solution. But, that solution would be even more of a mess than my current code (remember, I'm doing this for the readability).

So, is there an elegant solution for my problem in Java?

Jon Skeet
people
quotationmark

Well you could refactor that particular code to:

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

It's not fabulous, but it's still an improvement. Note that currently you're actually updating the field whether or not you logged about it - are you sure that's what you intended? I'd more expect something like:

if (update) {
    logUpdate(activity.getName(), name, "name", id);
    activity.setName(name);

    logUpdate(activity.getPlannedDuration(), plannedDuration,
             "planned duration", id);
    activity.setPlannedDuration(plannedDuration);
}

But no, there's no trivial way of passing methods around in Java at the moment. Java 8 will make it much simpler with method references and lambda expressions, however.

people

See more on this question at Stackoverflow