Paweł Sosnowski
Paweł Sosnowski

Reputation: 172

How to choose overloaded method by argument type?

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?

Upvotes: 3

Views: 747

Answers (2)

St&#233;phane D.
St&#233;phane D.

Reputation: 11

errors is a List so errors.get(0) is an ObjectError. According to this, the method taking an ObjectError is used because it is linked at compile time, not at runtime.

In order to do what you want, you should add a getMessage() method in your ObjectError class and override it for FieldError. And then, you really use polymorphism :

public class ObjectError {
  [...]
  public void getMessage() {
    return this.getDefaultMessage();
  }
  [...]
}

public class FieldError {
  [...]
  @Override
  public void getMessage() {
    return String.format("%s %s", this.getField(), this.getDefaultMessage());
  }
  [...]
}

Upvotes: 1

Eran
Eran

Reputation: 393771

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.

Upvotes: 7

Related Questions