1 静态成员变量
在类中定义的变量通常称之为成员变量,如果当一个成员变量的前面增加了修饰符Static,那么我们就称这个成员变量为静态成员变量。
1.1 成员变量和静态成员变量的定义方法
创建一个Car类,在其中定义了两个成员变量,一个是普通成员变量color,一个是静态成员变量myColor。
public class Car { public String color;//普通成员变量 public static StringmyColor;//静态成员变量 void show(){ System.out.println("汽车的颜色是"+this.color); System.out.println("我的汽车的颜色是"+this.myColor); } public static void main(String[]args) { Carcar=new Car(); car.show(); } }
运行结果为:
汽车的颜色是null
我的汽车的颜色是null
无论是成员变量还是静态成员变量在没有自定义初始化的时候,系统给的默认初始值都是null。在这一点上成员变量和静态成员变量是同样的。
1.2 静态成员变量的使用场合
1.2.1 成员变量的值在不同的对象中完全一样
一个类可以创建多个对象实例,每创建一个对象,就在内存中分配相应的一块空间,用来存储对象中的成员变量和方法。如果某一个成员变量在每一个对象中的值都是相同的,那么对于这个变量来说,每个对象中也同样分配了内存空间进行存储就造成了内存空间的浪费。如下图所示,图中的地址为演示用,并不是实际内存地址。(下同)
图1 定义普通成员变量时的内存地址的使用情况图
为了解决使用成员变量造成的内存空间的浪费,可以定义静态成员变量来解决这种内存空间的浪费。定义为静态成员变量的变量其分配的内存地址为共享数据内存地址,与对象分配的内存地址不在同一区域,而且只分配一次,不会因为对象的构建而重复分配。构建对象完成后,通过对象同样可以访问静态成员变量,达到与通过对象访问普通成员变量同样的效果。使用静态成员变量大大减少了内存空间的浪费情况,如下图所示。
图2 定义静态成员变量后的内存地址的使用情况图
1.2.2 类在加载过程中给变量赋值
有一个变量,希望这个变量在类的初始化过程中就给其赋值,如何才能完成这样一个功能?
我们知道普通成员变量的初始化需要先要构建类的对象。只有当类的对象存在后,才能给成员变量进行赋值。所以普通成员变量完成不了我们前面提出的需求。
那如何完成这个功能呢?这里就可以用到静态成员变量。由于静态成员变量是随着类的加载而加载的,也就是说在定义类的过程中,给类分配内存的同时,也给静态成员变量分配了内存。所以类加载后,静态成员变量也同时加载完毕。不用构建对象,可以直接访问静态成员变量。
public class Car { publicstatic String myColor="white"; publicstatic void main(String[] args) { System.out.println(“我的汽车颜色是”+myColor); } }
运行结果为:
我的汽车的颜色是white
从运行的结果,可以发现不构建类的对象,一样可以访问静态成员变量。这就解决了我们提出的问题。
我们使用类名访问了静态成员变量,那么如果使用对象能够访问静态成员变量吗?我们按照下面的代码进行修改。
public class Car { publicstatic String myColor="white"; publicstatic void main(String[] args) { Car car1=new Car(); System.out.println("我的第一辆汽车颜色是"+myColor); System.out.println(“我的汽车颜色是”+myColor); } }
运行结果为:
我的第一辆汽车颜色是white
我的汽车颜色是white
从运行结果我们发现静态成员变量不仅能够通过类访问,通过对象同样可以访问。
1.2.3 静态成员变量与成员变量的不同
静态成员变量和非静态成员变量虽然都是成员变量,但是其还是有不同之处,主要体现在以下几点:
1、存储地址不同,静态成员变量存储于数据共享区,成员变量存储于对象内存区;
2、生成的时间不同,静态成员变量在类生成的时候就同时存在了,而成员变量需要构建对象后才存在。
3、调用的不同,静态成员变量既能被类调用也能被对象调用,而成员变量只能被对象调用。