具有私有静态字段的超类和子类调用一个更改字段的方法,为什么字段不更改?

superclass with private static field and subclass calls a method that changes the field, Why doesn't the field change?

public class B {

    private static  boolean goo=true;

    protected static boolean foo() {
        goo=!goo;
        return goo;
    }

    public String bar="Base:"+foo();

    public static void main(String[] args)  {
        B base=new A();
        System.out.println("Base:"+goo);//***prints Base:true***
    }
}

public class A extends B{
    public String bar="Sub:"+foo();
}

为什么程序打印的是true而不是false,我不明白为什么调用foo()goo没有改变。 goo 未隐藏,因为它是私有字段。创建对象之前的静态字段是 true,那么当 foo 发生时,它不应该在堆中更改 goo 吗?

因为你改了两次值?

true -> public String bar="Base:"+foo(); -> false
false -> public String bar="Sub:"+foo(); -> true

原因在中有很好的解释,但您没有看到的是您有两个变量调用 bar,一个在 A 中,一个在 B 中.

如果您添加一个方法来打印 class 中的实例成员(并且 A 也将打印为超级 class):

public class Main {

    public static void main(String[] args) {
        B base = new A();
        System.out.println(base);
    }
}

class B {

    private static boolean goo = true;

    protected static boolean foo() {
        goo = !goo;
        return goo;
    }

    public String bar = "Base:" + foo();

    @Override
    public String toString() {
        return bar; //print the variable B.bar
    }
}

class A extends B {
    public String bar = "Sub:" + foo();

    @Override
    public String toString() {
        //print the instance B and the variable A.bar
        return super.toString() + "\n" + bar;
    }
}

您会看到 bar 都存在于一个实例中 A

Base:false
Sub:true

如果可访问性允许,您可以使用 super.bar 访问 B.bar 变量,但在您的情况下它是私有的。

一个解决方案是使用一个构造函数 B,它将接受一个值并连接 foo.

的结果
public String bar;

public B(){
    this("Base: ");
}

protected B(String source){ //protected to prevent anybody to use it directly
    bar = source + foo();
}

并且在A

public A(){
    super("Sub: ");
}

只有 B 的创建会调用 foo 所以你得到的结果是:

Sub: false

让我们检查一下:

System.out.println(new A().bar);
System.out.println(new B().bar);
System.out.println(new A().bar);

Sub: false
Base: true
Sub: false