How to choose overloaded method by argument type?

Paweł Sosnowski :

I'm trying to overload my method depending on the argument type:

FieldError extends ObjectError.

private String getMessage(final FieldError fieldError) {
    return String.format("%s %s", fieldError.getField(), fieldError.getDefaultMessage());
}

private String getMessage(final ObjectError objectError) {
    return objectError.getDefaultMessage();
}

Now, if I have a List<ObjectError> and call above method for elements of that List, regardless of which type (ObjectError or FieldError) the elements on the List are,
getMessage(final ObjectError objectError) will always be called.

enter image description here

List<ObjectError> errors;
getMessage(errors.get(0));

Why is it behaving this way? If it's just how it works, is there any chance not using if's and instanceof's?

Eran :

Method overloading resolution is performed at compile time, when only the compile-time type is known. Therefore, the compile-time type of the parameters passed to the method call determine which of the overloaded methods is chosen.

Since you are passing elements of a List<ObjectError> to the method call, String getMessage(final ObjectError objectError) is always chosen, and the runtime type of the instances stored in that List doesn't make a difference.

One way to solve your problem is to move the getMessage() method to ObjectError class, and override it in the FieldError sub-class.

Instead of

getMessage(errors.get(0))

you'll call

errors.get(0).getMessage()

This will work, since method overriding is resolved at runtime.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=88060&siteId=1