Java中的变量阴影
我对这个Java代码有一些疑问。它的输出是“毛茸茸的叫声”。我的问题是:Java中的变量阴影,java,Java,我对这个Java代码有一些疑问。它的输出是“毛茸茸的叫声”。我的问题是: 为什么我得到这个输出 如何访问ZooKeeper类中的字符串对象引用“name” 如果它与变量阴影有关,那么哪个变量被阴影 代码: 变量不是多态的。当您访问m.name时,无论对象的执行时间类型如何,都将始终使用作为该对象一部分的哺乳动物.name字段。如果需要访问Zebra.name,则需要编译时类型为Zebra的表达式 实际上调用了makeNoise方法-执行时使用的实现确实取决于对象的类型 请注意,如果您将所有字段都
变量不是多态的。当您访问
m.name
时,无论对象的执行时间类型如何,都将始终使用作为该对象一部分的哺乳动物.name
字段。如果需要访问Zebra.name
,则需要编译时类型为Zebra
的表达式
实际上调用了makeNoise
方法-执行时使用的实现确实取决于对象的类型
请注意,如果您将所有字段都设置为私有,这通常是一个好主意,但最终不会成为问题
这实际上是隐藏而不是阴影。有关隐藏和阴影的详细信息,请参见。我不能说我总是直截了当地保持差异…Java中没有变量重写,您在父级和子级中声明了名称,但通过父级引用变量引用了名称。这就是为什么你有“毛茸茸的”
方法有重写,这就是为什么您得到了bray。因为在运行时,它查看堆中的真实对象,发现它是一个Zebra。Java中的变量名是由引用类型解析的,而不是它们引用的对象。因此,m.name指的是哺乳动物中的变量名,即使m是斑马。之所以发生这种情况,是因为
哺乳动物中的名称字段被斑马隐藏。然后,您只需将其转换为所需类型即可访问它。
另一方面,makeNoise()
method重写父级的相同方法,因此您无法再从父级访问实现
输出为“毛茸茸的叫声”。请解释一下
java程序中的字段
不能通过动态查找进行访问。相反,它们是在编译时静态解析的。这就是为什么m.name
会让你毛茸茸的原因。然而,java程序中的方法是通过动态查找访问的。这就是为什么m.makeNoise()
会得到bray
我们如何访问name变量,即在
是吗
如果您想访问Zebra.name
,则应在“Zebra”中键入castm
。如下所示:
System.out.println(((Zebra)m).name + m.makeNoise());
更新
这里显示的现象是由而不是的结果。因此,为了获得正确的输出,您必须创建一个getter方法,如public String getName(){return this.name;}
是的,这就是我要做的。你也需要用斑马线来创建getter。@JonSkeet-谢谢。。。我从来不知道。。有一件事叫做隐藏变量@LuigiEdlCarno不是重写getter,在基类中为name
创建受保护的字段name
和公共getter,并在派生类的构造函数中分配name
不是更好吗?我发现这更符合逻辑,并且节省了很少的击键次数。@PLB:我想在超类中将其设为私有字段,但这取决于需要什么。我们这里没有真正的用例,没有解释这两个独立字段的含义;当子类和父类都有一个同名变量时,子类的变量隐藏父类的变量,因此当我们试图通过持有子类的对象从父类的引用访问变量时,它将从父类访问,请阅读我的博客上的更多信息
System.out.println(((Zebra)m).name + m.makeNoise());