一、概述
关于static,先做以下说明:
①被声明为static的变量、常量和方法称为静态成员,属于类所有,静态的成员属性为类的不同对象共享。
class Employee{
private int id;
private static int nextId=1;//这里声明了一个静态成员变量
}
比如对于上面的Employee类,如果创建了100个该类的实例,那么每个实例都有自己的id,也就有100个id分别占用不同地方的内存,但是只有一个静态成员变量nextId,只占用了一个内存,所有实例的nextId都是这一个。静态成员变量属于类,而不属于任何对象。
②一般用“类名.静态成员”的形式访问。“对象.静态成员”也可以访问,但是为了区分静态成员与非静态成员,请使用第一种方式。而且在myEclipse中使用第二种方式会有警告。
③static方法中不能使用this关键字。也许可以这样解释:静态方法是属于类的,而this在一个非静态方法中是一个隐式参数,代表调用该方法的类的实例,所以可以认为静态方法是没有this这个隐式参数的。同里也不能使用super关键字。
例如main方法就是静态方法,我们不需要创建对象,而是直接就调用main方法,main方法不对任何对象进行操作,事实上,在启动程序时,还没有任何一个对象,静态的main方法将执行并创建程序所需要的对象。
以下两种情况下使用静态方法:
一个方法不需要访问对象状态,其所需要的参数都是通过显示参数提供,如Math.pow。
一个方法只需要访问类的静态域,例如下面的Employee.getNextId。
public static int getNextId{
return nextId; //返回静态成员变量
}
那么可以直接使用 int n=Employee.getNextId(); 来访问这个方法。当然上面的方法也可以不用static,只不过这时候必须要通过对象来调用了。
④方法体中局部变量不能声明为static。
二、从内存分配上去理解static的特殊之处
当执行main函数时,首先sid是static成员变量,分配在data segment(数据区)中,就在data seg中存在了一个sid,其值为100,那么当new出来mimi时,还有name和id成员变量,id是基本数据类型,只需要一块内存,存放于栈中,new Cat("mimi")的形式参数属于局部变量,会在栈中为name分配一个空间,而“mimi”是字符串常量,应该放在data seg中,并且由name指向。此外,新new的对象还有id属性。此时内存分配如下:
构造函数的形式参数name(stack中的)与实例mimi的成员变量this.name(heap中)指向同一个字符串常量。但是当创建完对象后,作为形式参数的name将消失,同时由他指向字符串常量“mimi”的指针也消失。
当创建完两个实例后,内存分配如下:
从内存分配可以看出,虽然有两个Cat对象,但却只有一个sid.
三、例子
下面我只给出一个程序片段截图,这个图主要是static的具体例子,可以帮助理解(一)中的话,同时也还有其他static的注意事项,请参看注释。