JAVA: 子类通过static块使用父类成员变量的潜在风险
背景
这篇文章作为上一篇文章[JAVA: 子类“覆盖”父类的成员变量]的补充,主要说明子类通过static块“覆盖”父类成员变量时的一个潜在风险。
例子
先来看个例子,关于通过static块“覆盖”父类成员变量的情况
public class Person {
public static String name = "person";
}
public class Dad extends Person {
static {
name = "Dad";
}
}
public class Mom extends Person {
static {
name = "Mom";
}
}
public static void main(String[] args) {
System.out.println(Person.name);
System.out.println(Dad.name);
System.out.println(Mom.name);
Person dad = new Dad();
System.out.println(Person.name);
System.out.println(Dad.name);
System.out.println(Mom.name);
Person mom = new Mom();
System.out.println(Person.name);
System.out.println(Dad.name);
System.out.println(Mom.name);
}
输出结果为:
person
person
person
Dad
Dad
Dad
Mom
Mom
Mom
分析
如果单单只看这个简单例子,从static
的含义来说,问题很清楚;因为static
变量name
与Person
类是否实例化无关,当改变name
值时会使得所有的Person
类及其子类,以及实例中name
值都发生变化,即name
是共享的。
而static
块会在类初始化时执行,并且整个程序运行过程中只执行一次,而static
块中对name
值的修改就会在初始化时发生。所以例子中在Dad
类初始化时会修改name
为Dad
,Mom
类初始化时会修改name
为Mom
,而在Person
类及其子类中name
值都相同。
潜在风险
应当注意在某个类有多个子类时,子类对父类的static
成员变量是共享的,拿父类static
成员变量存储本子类独有的数据时,很可能引发错误。