Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 实例查找字段/变量赋值的奇怪行为_Java_Python - Fatal编程技术网

Java 实例查找字段/变量赋值的奇怪行为

Java 实例查找字段/变量赋值的奇怪行为,java,python,Java,Python,我正在探索Java中的方法和变量继承,特别是类的实例如何查找静态变量字段 然而,我无法在下面的Java片段中获得预期的行为 更令人费解的是,运行用Python编写的同样的东西可以得到预期的结果 分类{ 公共静态int n=1; 公共INTM; 公共空白设定者{ System.out.printlnI查找+this.n; 这个.m=这个.n; System.out.printlnith.m; } } 类Sub向上扩展{ 公共静态int n=6; 公共int m=5; 公共子系统{ 超级的 } }

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

然而,我无法在下面的Java片段中获得预期的行为

更令人费解的是,运行用Python编写的同样的东西可以得到预期的结果

分类{ 公共静态int n=1; 公共INTM; 公共空白设定者{ System.out.printlnI查找+this.n; 这个.m=这个.n; System.out.printlnith.m; } } 类Sub向上扩展{ 公共静态int n=6; 公共int m=5; 公共子系统{ 超级的 } } 班跑{ 公共静态无效字符串[]args{ Sub foo=新Sub; foo.setter; System.out.printlnfoo.m; } } 分类: n=1 def setterself: 普林蒂抬起头来,赛尔夫 self.m=self.n printself.m 类别分组: n=6 m=5 foo=Sub foo.setter printfoo.m Python代码按预期运行并打印出来:

I looked up 6
6
6
I looked up 1
1
5
但是,打印出的等效Java代码:

I looked up 6
6
6
I looked up 1
1
5
我想我这里有两个问题:

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

在成功查找1之后,Java应该将foo.m绑定到1。打印出this.m似乎表明它有,但是直接从main方法打印出foo.m表明它没有,这是为什么


我怀疑这是由于Java在运行时访问变量造成的,我仍在思考这个问题,我想这可以解释第1个问题,但我希望有人能向我解释第2个问题背后发生了什么

至于第二个问题,您有两个名为m的实例变量。一个在类Up中声明,另一个在类Sub中声明,该类在类Up中隐藏变量。因此,当您调用setter时,它是Up的一种方法,它使用Up中的m值,而不知道在它的任何子类中找到的变量

但是当您稍后打印foo.m时,因为foo是Sub的instacnce,所以它使用Sub中的m值,该值仍然是5


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

因为静态字段不会被继承。这个.n没有意义,因为n是静态的,这是一个实例。Java使用实例的静态类型来解析它,因此您正在访问Up.n。@Blorgbeard我理解实例的静态类型是指实例的类吗?实例的声明类,是的-因此,在这种情况下,它是向上的。这是在编译时发生的,因为静态没有继承/动态分派。@Blorgbeard啊,好吧,我明白你的意思了!知道了。所以Java在本例中将这个.m解释为Up中的静态字段,当我调用setter时,我实际上是在修改静态字段m;foo一点也没有被碰过?不,m在Up中不是一个静态字段。这是一个实例字段。Up的每个实例都有自己的m。由于setter是Up的一个方法,所以该方法不知道子类的实例字段——它只知道自己类Up的实例字段。。。因此,这个.m被解释为Up的特定实例的实例字段,即使不存在这样的实例?确保它存在。您在这里创建了它:Sub foo=new Sub;,变量foo是Up子类的一个实例,因此是Up。问题是Up不知道名为Sub的类的存在,因此Up中定义的方法除了Up.Ah中定义的变量外,对变量一无所知。我现在突然明白了。