说明丨本文来源网络或教材丨供学习交流用丨不属原创丨原创标识无用丨侵删
1、实例变量和类变量的声明
学习Java类的时候我们知道:类体中包括成员变量的声明和方法的定义,而成员变量又可细分为实例变量和类变量。在声明成员变量时,用关键字static给予修饰的称作类变量,否则成为实例变量(类变量也称为static变量、静态变量),例如:
class Person {
int x; //实例变量
static int y; //类变量
}
上述Person类中,x是实例变量,而y是类变量。需要注意的是,static需要放在变量的类型的前面。接下来说明实例变量和类变量的区别。
2、实例变量和类变量的区别
-
不同对象的实例变量互不相同
我们已经知道:一个类通过使用new运算符可以创建多个不同的对象,这些对象将被分配不同的(成员)变量。说得准确些就是:分配给不同对象的实例变量占有不同的内存空间,改变其中一个对象的实例变量不会影响其他对象的实例变量。 -
所有对象共享类变量
如果类中有类变量,当使用new运算符创建多个不同的对象时,分配给这些对象的这个类变量占有相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说,对象共享类变量。 -
通过类名直接访问类变量
当Java程序执行时,类的字节码文件被加载到内存,如果该类没有创建对象,类中的实例变量不会被分配内存。但是,类中的类变量,在该类被加载到内存时,就分配了相应的内存空间。如果该类创建对象,那么不同对象的实例变量互不相同,即分配不同的内存空间,而类变量不再重新分配内存,所有的对象共享类变量,即所有的对象的类变量是相同的一处内存空间,类变量的内存空间直到程序退出运行,才释放所占有的内存。
3、例子
有两个文件,分别是Person.java和Example.java文件。
Person.java文件
public class Person {
double height; //实例变量
static double width; //类变量
void setheight (double h) {
height = h;
}
void setwidth (double w) {
width = w;
}
void getheight () {
return height;
}
void getwidth () {
return width;
}
}
Example.java文件
public class Example {
public static void main (String args[]) {
Person.width = 100; //通过类名操作类变量
Person personone = new Person();
Person persontwo = new Person();
personone.setheight(28);
persontwo.setwidht(66);
Syntem.out.println("personone's height: "+personone.getheight());
Syntem.out.println("persontwo's height: "+persontwo.getheight());
Syntem.out.println("personone's width: "+personone.getwidth());
Syntem.out.println("persontwo's width: "+persontwo.getwidth());
}
}
【结果】是personone和persontwo的height变量的值分别为28和66,而两个对象的width变量值都为100。
【解释】上述例子从Example.java中的主类的main方法开始运行,当执行
Person.width = 100;
时,Java虚拟机首先将Person的字节码加载到内存,同时为类变量width分配了内存空间,并赋值100。
当执行
Person personone = new Person();
Person persontwo = new Person();
时,实例变量height两次被分配内存空间,分别为对象personone和对象persontwo所引用,而类变量width不再分配内存,直接别对象personone和对象persontwo引用、共享,如下图所示:
注:类变量似乎破环了封装性,其实不然,当对象调用实例方法时,该方法中出现的类变量也是该对象的变量,只不过这个变量和所有的其他对象共享而已。