Reputation: 172
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.
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
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
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