具有私有静态字段的超类和子类调用一个更改字段的方法,为什么字段不更改?
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
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