具有变量分配的实例查找字段/异常行为

时间:2019-06-27 17:53:43

标签: java python

我正在探索Java中的方法和变量继承,尤其是类的实例如何查找字段(静态变量)。

但是,我无法获得下面的Java片段中预期的行为。

更令人困惑的是,运行用Python编写的相同(?)东西可以获得预期的结果。

class Up {

    public static int n = 1;
    public int m;

    public void setter() {
        System.out.println("I looked up " + this.n);
        this.m = this.n;
        System.out.println(this.m);
    }
}

class Sub extends Up {

    public static int n = 6;
    public int m = 5;

    public Sub() {
        super();
    }
}

class Run {
    public static void main(String[] args) {
        Sub foo = new Sub();
        foo.setter();
        System.out.println(foo.m);
    }
}
class Up:
    n = 1

    def setter(self):
        print("I looked up", self.n)
        self.m = self.n
        print(self.m)

class Sub(Up):
    n = 6
    m = 5

foo = Sub()
foo.setter()
print(foo.m)

Python代码按预期运行并打印出来:

I looked up 6
6
6

但是,等效的Java代码已打印出来:

I looked up 1
1
5

我想我在这里有两个问题:

  1. Java为什么将this.n解释为Up类中初始化的字段而不是foo的实际类Sub?

  2. 在成功查找1之后,Java应该将foo.m绑定到1。打印出this.m似乎表明它已经拥有,但是直接从main方法中打印出foo.m表明它已经拥有了。不是,为什么呢?

我怀疑这是由于Java“在运行时访问变量”(我仍在解决这个问题)引起的,我猜这可能解释了数字1,但我希望有人能解释一下对我来说2号后面发生了什么?

1 个答案:

答案 0 :(得分:1)

对于第二个问题,您有两个名为“ m”的实例变量。在Class Up中声明的一个,在Sub类中声明的一个在Up中隐藏变量。因此,当您调用setter()(这是Up的方法)时,它将使用在Up中找到的m的值(Up不了解其任何子类中找到的变量)。

但是,当您以后打印foo.m时,由于foo是Sub的不变性,因此它将使用Sub中的m值(仍为5)。

删除Sub类中m的声明,看看会发生什么。