表明上看,Java类里定义成员变量时没有先后顺序,但实际上Java要求定义成员变量时必须采用合法的前后引用。示例如下
publicclassErrorDef {int num1 = num2 +5;//Cannot reference a field before it is definedint num2 =20; }
上面程序中定义num1成员变量的初始值时,需要根据num2变量的值进行计数,这就是“非法前后引用”。
类似地,两个类变量也不允许采用这样“非法前后引用”,示例如下。
publicclassErrorDef {staticint num1 = num2 +5;//Cannot reference a field before it is definedstaticint num2 =20; }
但如果一个是实例变量,一个是类变量,则实例变量总是可以引用类变量,示例如下
publicclassRightDef {int num1 = num2 +5;staticint num2 =20; }
上面程序中num1是一个实例变量,而num2是一个类变量。虽然num2位于num1之后被定义,但nun1的初始值却可根据num2计算得到。这是因为,num2变量是一个类变量,num1是实例变量,而类变量的初始化时机总是处于实例变量的初始化时机之前。所以,虽然源代码中先定义了num1,再定义了num2,但num2的初始化时机总是位于num1之前,因此num1变量的初始化可根据num2的值计算得到

实例变量和类变量的属性

使用static修饰的成员变量是类变量,属于该类本身;没有使用static修饰的成员变量是实例变量,属于该类的实例。在同一个JVM内,每个类只对应一个Class对象,但每个类可以创建多个Java对象。
由于同一个JVM内每个类只对应一个Class对象,因此同一个JVM内的一个类的类变量只需一块内存空间;但对于实例变量而言,该类每创建一次实例,就需要为实例变量分配一块内存空间。也就是说,程序中有几个实例,实例变量就需要几块内存空间。
下面程序可以很好地表现出来实例变量属于对象,而类变量属于类的特性。