如何按参数类型选择重载方法?
Posted
技术标签:
【中文标题】如何按参数类型选择重载方法?【英文标题】:How to choose overloaded method by argument type? 【发布时间】:2019-05-13 15:08:03 【问题描述】:我正在尝试根据参数类型重载我的方法:
FieldError 扩展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();
现在,如果我有一个List<ObjectError>
并为该List
的元素调用上述方法,无论List
上的元素是哪种类型(ObjectError
或FieldError
),getMessage(final ObjectError objectError) 将始终被调用。
List<ObjectError> errors;
getMessage(errors.get(0));
为什么会这样?如果它只是它的工作原理,有没有机会不使用if
's 和instanceof
's?
【问题讨论】:
【参考方案1】:方法重载决议在编译时执行,此时只有编译时类型是已知的。因此,传递给方法调用的参数的编译时类型决定了选择哪个重载方法。
由于您将List<ObjectError>
的元素传递给方法调用,因此始终选择String getMessage(final ObjectError objectError)
,并且存储在List
中的实例的运行时类型没有任何区别。
解决问题的一种方法是将getMessage()
方法移至ObjectError
类,并在FieldError
子类中覆盖它。
代替
getMessage(errors.get(0))
你会打电话的
errors.get(0).getMessage()
这会起作用,因为方法覆盖是在运行时解决的。
【讨论】:
【参考方案2】:errors
是一个 List,所以 errors.get(0)
是一个 ObjectError。
据此,使用 ObjectError 的方法是因为它是在编译时链接的,而不是在运行时。
为了做你想做的事,你应该在你的 ObjectError 类中添加一个getMessage()
方法,并为 FieldError 覆盖它。然后,你真的使用了多态性:
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());
[...]
【讨论】:
以上是关于如何按参数类型选择重载方法?的主要内容,如果未能解决你的问题,请参考以下文章