老司机请进关于java this关键字

请问怎么解释这个结果。图片

打印了两条记录,我一个一个跟你分析一下:
首先第一个:
打印的是子类的run方法,这个很好理解的,首先,你new 的是子类的对象,调用的是父类的run2()方法,此时,run2()方法中的this其实是子类的对象,你可以打印一个System.out.println(this.getClass()),确认一下,所以,子类对象就会看它自己有没有run()方法,很明显是有的,你可以理解为这是方法的重写,所以调用的就是子类的run()方法;
然后第二个问题:
为什么上面描述的this是子类对象,但是得到的却是父类的值呢?其实.run2()这个方法是属于父类的,父类是无法获得子类的属性的,方法可以重写,但是属性没有重写这个概念,当你调用this.(成员属性)的时候,查找属性值顺序:方法,成员,然后会去这个方法所在类的父类去找,就近原则返回结果,...但是,要注意的是,在父类里面是无法直接获得子类的成员变量的,要想获得,就要通过创建对象的方式来获取

下面给你一段代码,你可以用我的代码去实验一下:

public class Test {
/*public static void main(String[] args) {
Child child=new Child();
child.run2();
}*/
public static void main(String[] args) {
Man m=new Child();
System.out.println(m.age); //获得的是Man的属性值
m.run(); //调用子类的方法
}
}

class People{
    int age=100;
    public void run() {
        System.out.println("人类执行了");
    }
}

class Man extends People{

    public void run() {
        System.out.println("父类执行了");
    }

    public void run2() {
        this.run();
        System.out.println(this.getClass());
        System.out.println(this.age);
    }
}

class Child extends Man {
    int age = 10;
    public void run() {
        System.out.println("子类执行了");
    }
}

this指向被加载到jvm的具体对象,也就是demo2,所以this.run和this.a都是demo2中的

运行Demo2.run2()首先从demo2类里找run2()方法,没找到就去父类demo3找到run2方法,
执行demo3中run2()里的this.run()时,demo2类和demo3类都存在run()方法,调用了子类demo2里的run(),
最后执行输出语句this.a就是demo3的a=3

this是指具体使用的一个对象,也就是JVM真正调用的对象,但是this.属性时,它指的是this所在本类的属性,如果本类没有该属性,JVM就会一直查找它的上层类,直到找到这个属性,更重写差不多的意思,但如果是在父类里面使用this.属性,因为父类并不能使用子类的属性和方法,所以JVM在编译的时候就已经决定了它使用的是自己的属性,要不然编译报错,如果你想它打印子类的4,你就必须遵守子类能使用父类和本身类的属性和方法,且子类覆盖父类,父类不能使用子类的属性和方法的规则,要不然JVM还怎么工作啊,所以你把它写在子类的某个方法里面就可以了。

我的理解这样的:
1. 程序首先创建demo2对象,完成之后再到Demo2类中寻找run2方法,发现没有;
2. 因为Demo2继承了Demo3,所以接着会到Demo3中去找这个方法,发现有这个方法;
3.接着执行这个方法里面的this.run(),此时需要知道这个this指代的是什么,当this后面跟方法时指代的是引用对象,我们可以看到最初的对象是Demo2类,所以会执行Demo2中的run方法,输出“”子类的run“”;
4最后需要输出的就是this.a,跟前面大神们说的一样,当this后面跟属性的时候,指代的是所在的类对象,那么能够跟的属性也就是这个类中的属性,不然也得不到值,很明显this指代的是Demo3类,该类中的a的值为3,所以接着输出结果为3。程序运行结束。
希望能帮到您。

1.这里是java继承中的名称隐藏(hide)和重载(override)的概念,变量只有隐藏的机制,只有实例方法才会有动态绑定
2.this始终绑定的是当前对象,即new的时候返回的对象,并不会因为出现父类还是子类中而改变

建议参考下这篇文章,http://www.weixueyuan.net/view/5988.html