Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.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 - Fatal编程技术网

Java中的变量阴影

Java中的变量阴影,java,Java,我对这个Java代码有一些疑问。它的输出是“毛茸茸的叫声”。我的问题是: 为什么我得到这个输出 如何访问ZooKeeper类中的字符串对象引用“name” 如果它与变量阴影有关,那么哪个变量被阴影 代码: 变量不是多态的。当您访问m.name时,无论对象的执行时间类型如何,都将始终使用作为该对象一部分的哺乳动物.name字段。如果需要访问Zebra.name,则需要编译时类型为Zebra的表达式 实际上调用了makeNoise方法-执行时使用的实现确实取决于对象的类型 请注意,如果您将所有字段都

我对这个Java代码有一些疑问。它的输出是“毛茸茸的叫声”。我的问题是:

  • 为什么我得到这个输出
  • 如何访问ZooKeeper类中的字符串对象引用“name”
  • 如果它与变量阴影有关,那么哪个变量被阴影
  • 代码:
    变量不是多态的。当您访问
    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”中键入cast
    m
    。如下所示:

    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());