7.4 static关键字
在通常情况下,要使用一个类对象(实例)的公有成员变量,需要通过这个类实例化出对象,再通过“对象名.变量名”的形式访问。作为程序员,有时需要定义一个类级别的变量,它的使用完全独立于该类的任何对象,可以直接通过“类名.变量名”的形式进行访问。
在类成员的声明前,加上static(静态的)关键字,就能创建出这样的静态类成员。static成员最常见的例子是main方法。因为在程序开始执行时必须调用main方法,所以将它声明为static。
声明为static的变量称为静态变量或类变量。可以直接通过类名引用静态变量,也可以通过实例名来引用静态变量,但最好采用前者,因为采用后者容易混淆静态变量和实例变量。静态变量是跟类相关联的,类的所有实例共同拥有一个静态变量。
声明为static的方法称为静态方法或类方法。静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法。静态方法中不能使用this关键字,因为静态方法不属于任何一个实例。
7.4.1 static关键字的使用
1.用static修饰类的成员变量
用static修饰的类的成员变量是静态变量,对该类的所有实例来说,只有一个静态值存在,所有实例共用一个变量。静态变量是指不管类实例化出多少个对象,系统仅在第一次调用类的时候为静态变量分配内存。先来看下面的例子。
public class TestStatic
{
public static void main(String[] args)
{
Student wangYun = new Student();
wangYun.avgAge = 22; //将Student类变量的值设置为22
System.out.println("王云所在班平均年龄为:" + wangYun.avgAge);
Student liuJT = new Student();
liuJT.avgAge = 21; //将Student类变量的值设置为21
System.out.println("王云所在班平均年龄为:" + wangYun.avgAge);
System.out.println("刘静涛所在班平均年龄为:" + liuJT.avgAge);
}
}
class Student
{
public static int avgAge; //类变量,存放平均年龄
}
程序运行结果如图7.10所示。
通过程序运行结果可以看出,所有Sutdent类的实例wangYun和liuJT都共用了静态变量avgAge,当给其中任何一个实例的静态变量赋值,都是对这一个静态变量进行操作。
2.用static修饰类的成员方法
用static修饰类的成员方法表示,该方法被绑定于类本身,而不是类的实例。看下面的例子。
public class TestStatic2
{
public static void main(String[] args)
{
Student.showAvgAge(); //调用静态方法
System.out.println("静态变量输出所在班平均年龄为:" + Student.avgAge);
}
}
class Student
{
public static int avgAge = 22; //类变量,存放平均年龄
public static void showAvgAge() //静态方法输出班平均年龄
{
System.out.println("静态方法输出所在班平均年龄为:22");
}
}
程序运行结果如图7.11所示。
注意,在TestStatic2程序的main方法中,都是通过“类名.静态变量名”和“类名.静态方法名”的形式访问静态变量和调用静态方法的。通过“类实例.静态变量”和“类实例.静态方法”也可以访问静态变量和调用静态方法,但不推荐使用。
3.静态方法不能操作实例变量
静态方法可以操作静态变量,不能操作实例变量,可以通过下面的例子看出。
public class Student
{
public int avgAge = 22; //实例变量,存放平均年龄
public static void showAvgAge() //静态方法调用实例变量——编译出错
{
System.out.println("静态方法输出所在班平均年龄为:" + avgAge);
}
}
编译时报错,如图7.12所示。
7.4.2 Java静态块
第6章学习了对象的初始化过程,在使用new关键字创建并初始化对象的过程中,具体的初始化分为以下4步。
(1)给对象的实例变量分配空间,默认初始化成员变量。
(2)成员变量声明时的初始化。
(3)初始化块初始化。
(4)构造方法初始化。
接下来将会先介绍什么是Java静态块,并结合对象的初始化过程,介绍静态变量、静态块的执行顺序。
静态块的语法形式如下。
static
{
语句块
}
Java类首次装入JVM时,会对静态变量(含静态块)或方法进行一次初始化,方法不被调用是不会执行的,就是说静态变量和静态块是在类首次装载进JVM时被执行的。
运行如下的程序,运行结果如图7.13所示。
public class Student
{
private static String staticName = "静态姓名"; //静态变量
private String stuName = ""; //学生姓名——私有变量
//使用静态初始化块初始化
static
{
System.out.println("***使用静态初始化块初始化***");
System.out.println("静态块里显示静态变量值:" + staticName);
}
//使用初始化块初始化
{
this.stuName = "雷静";
System.out.println("***使用初始化块初始化***");
System.out.println("普通块里显示实例变量值:" + stuName);
System.out.println("普通块里显示静态变量值:" + staticName);
}
//构造方法,用户初始化对象的成员变量
public Student(String name){
this.stuName = name;
System.out.println("***使用有参构造函数初始化***");
System.out.println("构造方法里显示实例变量值:" + stuName);
System.out.println("构造方法里显示静态变量值:" + staticName);
}
public static void main(String[] args)
{
Student stu = new Student("王云");
}
}
通过上面的例子可以看出,静态变量和静态块都是在类实例化对象前被执行的。