zoukankan      html  css  js  c++  java
  • 一个Java的小问题

      老师今天在讨论群里抛出了一个问题,让大家尝试思考一下他所给的一段代码输出是什么。

      其代码如下:

      

    class T {
        void foo() { this.bar(); }
        void bar() { System.out.println("T.bar"); }
        public static void main(String args[]) {
            B b = new B();
            b.foo();
        }
    }
    
    class B extends T {
        void foo() { super.foo(); }
        void bar() { System.out.println("B.bar"); }
    }

      思考了一波:

        实例化子类对象,子类父类都没有显式构造器,就是在子类父类方法之间跳来跳去的。

      “嗯,答案一定是'T.bar'”。

      但还是敲了一遍,发现答案竟然是'B.bar'......(如图)

      室友说:“对啊,this不就是指向当前对象嘛...”

      (啪,打脸...疼...)

      重新审视了一遍,才发现自己对于this还是没理解到位...

      也就是说,整段代码执行流程如图:

      问题就在于this.bar()的指向问题... 平时一般遇到this一般都会在本类里(这里就是T类)去找是否有将之实现的方法,若有,就是它了。

      但是这次不同,事实上,正是this,使得当前方法指向其具体的对象,当这个对象实现了这个方法(这里的B类里将bar()方法覆盖了),自然this.bar()就会指向子类实现的这个bar()方法。

      本质上,输出B.bar是方法覆盖的问题,但自己犯错的原因是this的指向问题。

      因此,当我们稍微改一下代码。

      将B类的bar方法注释掉,让其不能覆盖其父类T的bar方法,结果this依旧是指向B类对象,但要调用bar方法时,发现B类没有bar方法的实现,因此“追溯”到B的父类中去寻找bar方法,此时找到了父类的bar方法并将其调用,输出自然也就是T.bar(如图)。

      

      此时,再来看另一种改动:只是在父类T中删掉了this,运行结果如图:

      可以看到,程序的输出结果依旧是B.bar。(这或多或少超出了我的预料)

      也就是说,这时的程序,和含有this关键字时,是一样的......

      这道题给我的印象还是很深刻的,毕竟自己看完题之后,竟然一点儿都不谦虚地直接喊出了一个错误答案...

      以后一定会多多注意this和super这样的很容易“改变”程序流程的关键字...

  • 相关阅读:
    聊聊我在微软外服大数据分析部门的工作经历及一些个人见解
    WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化)
    WPF Calendar 日历控件 样式自定义
    c# 委托 事件 lamda 简写
    WPF 启动唯一程序(项目,exe,实例)
    WPF 控件 深度克隆
    c# 枚举操作 正运算 逆运算
    WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂
    WPF查找子控件和父控件方法
    建立小型开发团队的工作协作:任务日历
  • 原文地址:https://www.cnblogs.com/stevenshen123/p/8625326.html
Copyright © 2011-2022 走看看