【问题标题】:Which method will be called when overriding a method with different parameters in the following case?在以下情况下,当覆盖具有不同参数的方法时,会调用哪个方法?
【发布时间】:2012-12-15 23:22:53
【问题描述】:

假设我要重写 Object 的 equals() 方法:

    public boolean equals(Object o){
      //something
    }

    public boolean equals(SomeClass s){
      //something else
    }

SomeClass 显然也是一个Object,那么如果我使用equals 和SomeClass 的Instance 作为参数,会调用哪个方法呢?

【问题讨论】:

  • 这是重载,调用重载方法的决定发生在编译时,因此调用具有参数 SomeClass 的方法
  • 会调用哪个方法?为什么不写个测试用例,20-30行java代码就行了。
  • @AmitD 他说了一个例子。我们不知道引用 SomeClass 对象的变量的类型。
  • 这是不正确的。请参阅 Costi 的答案。
  • @user802421 这是编译时的决定,所以如果你引用 Object 方法并调用对象。

标签: java object equals


【解决方案1】:

这不是压倒一切,而是超载。如果你这样做,你最终会得到两个 equals 方法:一个将为 SomeClass 实例的(子类)调用,另一个为任何其他对象调用。

需要注意的一点是方法绑定是静态的:编译器将根据声明的引用类型决定调用哪一个。因此,以下将调用equals(Object),而不是equals(SomeClass)

Object o = new SomeClass();
o.equals(o);  // invokes SomeClass.equals(Object)

【讨论】:

  • 感谢您的回答。有没有办法避免帖子第二段中描述的行为?
  • 不,唯一的方法是坚持覆盖equals(Object) 方法并在内部执行一些instanceof 测试。
【解决方案2】:

如果您像示例中那样重载函数,并正常实例化对象,则如果您向 equals 函数提供 SomeClass,则将以 SomeClass 作为参数的 equals 函数将被调用。对于任何其他类,将调用以 Object 为参数的 equals 函数。

但是,如果您将对象实例化为父类,则行为会有所不同。这与动态绑定有关,这里解释得很好:Question about Java overloading & dynamic binding

请注意,如果您希望在 Object 属于 SomeClass 类型时执行其他操作,您也可以在标准 equals 函数中使用 instanceof SomeClass。 (不想开始讨论,但这是一种选择)

【讨论】:

    【解决方案3】:

    您的public boolean equals(SomeClass s) 将在您使用参数SomeClassSomeClass 的子类调用它时被调用。

    对于任何其他对象,它将被称为 public boolean equals(Object o)

    但是当您在其他 API 中调用 equals 方法时,它们将调用 public boolean equals(Object o)。这将导致错误的行为。 Java Collection API 就是一个例子。

    所以不要像这样重载equals方法。

    【讨论】:

    • equals(SomeClass s) 也将使用SomeClass 的子类型参数调用
    猜你喜欢
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2020-02-28
    • 2012-11-10
    • 1970-01-01
    相关资源
    最近更新 更多