解释变量隐藏在此 Java 代码中的工作原理

2022-09-02 04:16:38

考虑以下代码

class A
{
    int x = 5;
    void foo()
    {
        System.out.println(this.x);
    }
}
class B extends A
{
    int x = 6;
    // some extra stuff
}
class C
{
    public static void main(String args[])
    {
         B b = new B();
         System.out.println(b.x);
         System.out.println(((A)b).x);
         b.foo();
    }
 }  

程序的输出是

6
5
5

我理解前两个,但无法理解最后一个。b.foo() 如何打印 5.B 类将继承 foo 方法。但是它不应该打印b.x打印的东西吗?这里到底发生了什么?


答案 1

是的,该类继承该方法。但是 中的变量隐藏了 in ;它不会取代它。BfooxBxA

这是一个范围问题。中的方法只能看到作用域中的变量。作用域中唯一的变量是 中的实例变量。fooAxA

该方法在 中继承,但不会被重写。如果要使用相同的确切代码显式覆盖:fooBfoo

class B extends A
{
    int x = 6;

    @Override
    void foo()
    {
        System.out.println(this.x);
    }
}

然后,当 被 引用时,在作用域内的变量将是 's ,并且将被打印出来。虽然方法的文本相同,但由于范围的不同,引用是不同的。this.xBx6

顺便说一句,如果您真的想在类中引用 's,则可以使用 。AxBsuper.x


答案 2

好吧,这是因为静态绑定。

1) Java 中的静态绑定发生在编译时,而动态绑定发生在运行时。

2)私有方法,最终方法和静态方法和变量使用静态绑定并由编译器绑定,而虚拟方法在运行时基于运行时对象绑定。

3) 静态绑定使用 Type(Java 中的类)信息进行绑定,而动态绑定使用 Object 来解析绑定。

4) 重载方法使用静态绑定进行绑定,而重写的方法在运行时使用动态绑定进行绑定。