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
成员变量存储本子类独有的数据时,很可能引发错误。
写的很细致,但是
public class Dad extends Person
子类被命名为Dad, 直接看输出结果,差点就记反了