例如String类的valueOf(int arg0)方法,作用是得到整数参数arg0的字符串表示,不需要创建出一个String类的实例对象来调用这个方法,所以它是static的。
如果你学过C/C++,你就会知道C/C++程序有一个入口,就是main()函数。电脑执行C/C++程序的时候就以main()函数作为入口,首先执行main()函数。Java也是类似,JVM首先调用main()方法。这个时候还没有什么实例对象呢,所以必须把main()方法声明为static,以便JVM调用。
如果是在类中变量前加static修饰的话,就是另外一个意思了。例如“人”这个类,有一个成员变量叫做“姓名”。现在new一个“人”的实例对象叫做“张三”,再new一个“人”的实例对象叫做“李四”。张三、李四自然有各自的“姓名”,它们的“姓名”成员变量在内存当中各自占一块存储单元,互不干扰。但是,如果在“人”这个类的“姓名”成员变量前加上static修饰的话,那么就变成了类变量。还是new出来“张三”“李四”,这次张三、李四的“姓名”在内存中就不是各自独立的存储区域了,而是共用一个存储区域。所有“人”的实例对象的“姓名”其实都是指的那一个存储单元。无论创建10个“人”对象还是100个“人”对象,它们的“姓名”指向的都是内存中的那一个存储单元。如果被更改了,实际上所有的对象的“姓名”都会改了,因为它们引用的都是内存中的那一个存储单元。就好像这个变量是属于类而不是属于实例对象的。
静态方法因为不需要实例对象就可以调用,所以当然其中也不可以使用实例对象变量。原因很简单啊,调用静态方法的时候怎么知道实例对象有没有创建、实例对象变量有没有初始化过呢。还是拿String类的valueOf()方法举例。假设valueOf()方法里面调用了String的一个实例对象str的某个成员变量。
那么以下这行代码
String.valueOf(10)
执行的时候,如何确定此时str对象就一定被创建出来并且成员变量都初始化过有值了呢?
(1)设置变量的存储域,函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;(2)限制变量的作用域,在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)限制函数的作用域,在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的static成员变量意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。