-3
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,我不明白为什么在被调用goo后没有改变。没有隐藏,因为它是一个私有字段。创建对象之前的静态字段是,那么当它发生时它不应该在堆中改变吗?foo()gootruefoogoo

4

2 回答 2

3

因为你改变了两次价值?

true -> public String bar="Base:"+foo(); -> false
false -> public String bar="Sub:"+foo(); -> true
于 2018-07-18T08:16:30.967 回答
2

原因在Panz0r 的回答中得到了很好的解释,但你没有看到的是你有两个变量 call bar,一一AB.

如果您添加一个方法来打印两个类中的实例成员(并且A还将打印超类):

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

基数:假
子:真

如果可访问性允许,您可以使用变量访问B.bar变量super.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,所以你会得到结果:

子:假

让我们检查一下:

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

子:假
基数:真
子:假

于 2018-07-18T08:25:20.300 回答