1

I have a class with an overloaded function, and was expecting Java to use the most specific implementation based on runtime type. However, it is always invoking the more generically-defined method in the below situation. Why is this?

I added comments in the code where the action is happening.

/** The entity class inheritance */
public abstract class AbstractHistory { }

public class IndicatorHistory extends AbstractHistory { }


/** The config class inheritance */
public class SynchResourceConfig { }

public class SynchIndicatorSenderConfig extends SynchResourceConfig { }


/** Class with overloaded methods */ 
public class ConfigFilter {

    public boolean shouldProcess(AbstractHistory history, SynchResourceConfig config) {
        logger.info("Using basic filter config");
        return config.isEnabled();
    }

    public boolean shouldProcess(IndicatorHistory history, SynchIndicatorSenderConfig sender) {
        logger.info("Using the Indicator sender config");
        return true;
    }
}

/** Use of the actual method */
private void updateCatalogWithHistoryData(MyType type, SynchResourceSettings senderSettings, long lastId) {
        HistoryDao historyDao = daoService.lookup(type);
        SynchResourceConfig savedConfig = senderSettings.getResources().get(type);

        // The below line always invokes the less specific method
        // (AbstractHistory history, SynchResourceConfig config)
        // even tho, when debugged, it definitely passes objects with runtime values of
        // (IndicatorHistory history, SynchIndicatorSenderConfig sender)
        Predicate<AbstractHistory> filter = (history) -> configFilter.shouldProcess(history, savedConfig);
        historyDao.findById(lastId).filter(filter).forEach(sendRecord(type)));
    }
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Cuga
  • 17,668
  • 31
  • 111
  • 166
  • 2
    Java looks at the *run-time type* of `this` but the *compile-time types* of arguments. This is known as **single dispatch**. Languages that also look at argument types at run-time have **multiple dispatch**, but Java's not one. See the linked question for more details. – John Kugelman Oct 08 '19 at 20:20
  • Thanks! I had not realized the distinction between 'this' vs arguments. – Cuga Oct 08 '19 at 21:21
  • @JohnKugelman If you don't mind my asking. Would it be feasible to use the Visitor pattern when the overloaded methods hinge on 2 differing variables as in this situation? – Cuga Oct 08 '19 at 22:29
  • Hm. Seems difficult. The simplest option might just be some basic `instanceof` checks. Not elegant, but effective. – John Kugelman Oct 09 '19 at 00:14
  • Thanks again! It's encouraging to know it isn't straightforward and wasn't just me. – Cuga Oct 09 '19 at 00:44

0 Answers0