但由于这个实例并不拥有这个类变量,因此它访问的并不是这个实例的变量,依然是访问它对应类的类变量。也就是说,如果通过一个实例修改了类变量的值,由于这个类变量并不属于它,而是属于它对应的类。因此,修改的依然是类的类变量,与通过该类来修改类变量的结果完全相同,这会导致该类的其他实例来访问这个类变量时也将获得这个被修改过的值。
class Person{
public String name;
public static int eyeNum;
}
public class PersonTest {
public static void main(String[] args) {
System.out.println("Person的eyeNum类变量值:" + Person.eyeNum);
Person p = new Person();
System.out.println("p变量的name变量值是: " + p.name + " p对象的eyeNum变量值是: " + p.eyeNum);
p.name = "孙悟空";
p.eyeNum = 2;
System.out.println("p变量的name变量值是: " + p.name + " p对象的eyeNum变量值是: " + p.eyeNum);
System.out.println("Person的eyeNum类变量值:" + Person.eyeNum);
Person p2 = new Person();
p2.name = "张三";
p2.eyeNum = 3;
Person p3 = new Person();
p3.name = "李四";
p2.eyeNum = 4;
System.out.println("p1对象的eyeNum类变量值:" + p.eyeNum);
System.out.println("Person的eyeNum类变量值:" + Person.eyeNum);
System.out.println("p2对象的eyeNum类变量值:" + p2.eyeNum);
System.out.println("p1对象的name类变量值:" + p.name);
System.out.println("p2对象的name类变量值:" + p2.name);
System.out.println("p3对象的name类变量值:" + p3.name);
}
}
outputs:
Person的eyeNum类变量值:0
p变量的name变量值是: null p对象的eyeNum变量值是: 0
p变量的name变量值是: 孙悟空 p对象的eyeNum变量值是: 2
Person的eyeNum类变量值:2
p1对象的eyeNum类变量值:4
Person的eyeNum类变量值:4
p2对象的eyeNum类变量值:4
p1对象的name类变量值:孙悟空
p3对象的name类变量值:李四
p2对象的name类变量值:张三
当Person类初始化完成后,系统将在堆内存中为
Person类分配一块内存区,在这块内存区里包含了保存eyeNum类变量的内存,并设置eyeNum的默认初始值:0.
系统接着创建了一个
Person对象,并把这个Person对象赋给p变量,Person对象里包含了名为name的实例变量,实例变量是在创建实例时分配内存空间并指定初始值的。
eyeNum类变量并不属于
Person对象,它是属于Person类的,所以创建第一个Person对象时并不需要为eyeNum类变量分配内存,系统只是为name实例变量分配了内存空间,并指定默认初始值:null.
接着执行Person p2 = new Person();代码创建第二个
Person 对象,此时因为Person 类已经存在于对内存中了,所以不再需要对Person 类进行初始化。创建第二个Person 对象与创建第一个Person 对象并没有什么不同。
name实例变量是属于单个
Person实例的,因此修改第一个Person对象的name实例变量时仅仅与该对象有关,与Person类和其他Person对象没有任何关系。同样,修改第二个Person对象的name实例变量时,也与Person类和其他Person对象无关。
执行p.eyeNum = 2;代码时,此时通过
Person对象来修改Person的类变量,Person对象根本没有保存eyeNum这个变量,通过p访问的eyeNum类变量,其实还是Person类的eyeNum类变量。因此,此时修改的是Person类的eyeNum类变量。
当通过p来访问类变量时,实际上访问的是
Person类的eyeNum类变量。事实上,所有的Person实例访问eyeNum类变量时都将访问到Person类的eyeNum类变量,本质其实还是通过Person类来访问eyeNum类变量时,他们所访问的是同一块内存。因此,建议当程序需要访问类变量时,尽量使用类作为主调,而不要使用对象作为主调,这样可以避免程序产生歧义,提高程序的可读性。