为了账号安全,请及时绑定邮箱和手机立即绑定

Java动态绑定和方法覆盖

Java动态绑定和方法覆盖

慕婉清6462132 2019-10-15 15:43:05
昨天我接受了两个小时的技术电话面试(我通过了,woohoo!),但是我完全想出了以下有关Java动态绑定的问题。令人困惑的是,几年前我曾当过助教时曾向大学生教授这一概念,所以我给他们提供错误信息的前景有点令人不安...这是给我的问题:/* What is the output of the following program? */public class Test {  public boolean equals( Test other ) {    System.out.println( "Inside of Test.equals" );    return false;  }  public static void main( String [] args ) {    Object t1 = new Test();    Object t2 = new Test();    Test t3 = new Test();    Object o1 = new Object();    int count = 0;    System.out.println( count++ );// prints 0    t1.equals( t2 ) ;    System.out.println( count++ );// prints 1    t1.equals( t3 );    System.out.println( count++ );// prints 2    t3.equals( o1 );    System.out.println( count++ );// prints 3    t3.equals(t3);    System.out.println( count++ );// prints 4    t3.equals(t2);  }}我断言输出应该是覆盖equals()方法中的两个单独的打印语句:at t1.equals(t3)和t3.equals(t3)。后一种情况足够明显,而在前一种情况下,即使t1具有Object类型的引用,也将其实例化为Test类型,因此动态绑定应调用该方法的重写形式。显然不是。面试官鼓励我自己运行该程序,瞧瞧,被覆盖的方法只有一个输出:在线t3.equals(t3)。我的问题是,为什么?正如我已经提到的,即使t1是对Object类型的引用(所以静态绑定将调用Object的equals()方法),动态绑定也应根据引用的实例化类型来调用方法的最特定版本。我想念什么?
查看完整描述

3 回答

?
森栏

TA贡献1810条经验 获得超5个赞

Java对重载方法使用静态绑定,而对重载方法使用动态绑定。在您的示例中,equals方法被重载(与Object.equals()具有不同的参数类型),因此所调用的方法在编译时绑定到引用类型。


这里一些讨论


它是equals方法的事实并不重要,除了重载而不是覆盖它是一个常见错误之外,您已经根据面试中对问题的答案意识到了这一点。


编辑:这里也是一个很好的描述。本示例显示了与参数类型有关的类似问题,但是是由同一问题引起的。


我相信,如果绑定实际上是动态的,则在任何情况下调用方和参数都是Test实例的情况都将导致调用重写的方法。因此,t3.equals(o1)将是唯一无法打印的情况。


查看完整回答
反对 回复 2019-10-15
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

equals方法Test不会覆盖的equals方法java.lang.Object。看参数类型!所述Test类被重载equals用一个接受的方法Test

如果equals要覆盖该方法,则应使用@Override批注。这将导致编译错误指出此常见错误。


查看完整回答
反对 回复 2019-10-15
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

有趣的是,在Groovy代码(可以将其编译为类文件)中,除一个调用外,所有调用都将执行print语句。(将测试与对象进行比较的人显然不会调用Test.equals(Test)函数。)这是因为Groovy DOES完全进行了动态类型化。这是特别令人感兴趣的,因为它没有任何显式动态键入的变量。我已经在几个地方读到了这被认为是有害的,因为程序员期望使用groovy来完成Java任务。


查看完整回答
反对 回复 2019-10-15
  • 3 回答
  • 0 关注
  • 411 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信