在Java类中灵活使用Static关键字
用专业术语来说,只有利用了new关键字创建对象后,才会在系统中为其创建存储空间。不过在有些特殊的情况下,程序员可能希望在没有创建对象的时候就能够为某个特定的成员分配存储空间或者可以调用某个方法等等。在Java中能否实现这个需求呢?
一、不建立对象即想使用的两种实际情况。
笔者提到的这个问题是否是无中生有呢?其实不然。在实际应用程序开发中,就经常会遇到这种情况。如现在需要三个对象,分别用来计算圆的面积、圆球的体积、圆柱的体积。在这三个对象的方法中,都需要用到一个叫做圆周率的常量,而且这个圆周率是固定不变的。所以,在程序开发中,对于这些公用的成员变量最好能够统一管理。当调整成员变量的精度时,其运算结果的精度也会随之调整。从程序员的角度来看,这就是要求在没有创建对象之前就要给成员变量分配存储空间,以方便其他的类可以因用这个变量。而这个需求如果没有Statci关键字的话就无法实现。
第二种情况就是程序员可能希望某个方法不予包含它的类的任何对象关联在一起。这个读起来可能有点拗口。简单的说,就是即使没有使用new关键字创建对象的情况下,程序员仍然能够调用这个方法。也就是说,在创建类的时候就需要为这个方法分配存储空间。就好像造汽车时,在做汽车设计图纸时就需要把发动机准备好。那么即使汽车还没造好,这个发动起也可以先拿来看看。此时也需要采用Static关键字来完成这个需求。
二、Static关键字的用途。
简单的说,Static关键字的用途就是在创建类的时候就给特定的成员或者方法分配存储空间。当程序员在成员变量或者方法前面加上Static关键字时,就表示这些成员与方法不会与包含它的那个类的任何对象实例关联在一起。换一句话就是说,即使没有创建这个类的对象,程序员仍然可以调用这个类中的成员或者方法。因为他们实际上已经存在,系统已经为他们分配了存储空间。不过需要注意的是,Static关键字定义的成员与方法,毕竟与传统的对象创建方法有所差异。所以无论是在定义时还是在具体的引用过程中,都有所差异。程序开发人员必须了解这种差异,并在实际的工作中要引起重视。特别是如果有其他语言开发经验的程序员,不要将Java语言的这个特性与其他语言搞混,否则的话很容易出现错误。
三、利用Static关键字来定义成员变量。
如上面那个案例中,需要定义一个类,然后在这个类中需要用到一个叫做圆周率的成员。如果我们将这个成员命名为pi,则这个类可以按照下面的方法定义成员变量。
Class circle{ Static float pi=3.14 }
这个类的定义跟其他类最大的不同,就是在成员变量前面加了一个static关键字。此时就将这个成员变量设置为了staitc状态。其实在创建这个类的时候,系统就为其分配了一份存储空间。而不是在创建对象的时候再创建的。也就是说,现在就将这个成员变量跟包含它的类独立出来。在这种情况下,如果利用new关键字来创建对象,那么这个成员变量都是指向同一个。即程序员如果利用这个类创建三个对象时,其成员变量pi都指向同一个存储空间。为此不同对象内的成员变量pi的值都是相同的,因为其实际上都指的是同一东西。所以说,要统一多个对象中成员变量的值是非常简单的。只需要在定义类的时候,在这个成员变量的前面加上关键字static即可。
那么该如何引用这个成员变量呢?据笔者所知,现在主要有两种引用的方法。不过笔者只用其中的一种。第一种方式就是跟传统的引用方式相同。也就是说,第一步是创建类(根据需要可以在某个成员变量前面利用static关键字加以修饰),第二步是创建对象,第三步就是通过对象来引用成员变量。引用的格式就是对象名.成员变量。这种方法就是比较传统的方法,通过对象去定位成员变量。很明显,如果采用这种方法的话,在代码中就不能够体现这个成员变量到底是static变量呢,还是非static变量。所以说这会给程序员阅读代码带来麻烦。
第二种方法是直接通过类来调用。也就说可以通过类名.成员变量的形式来加以调用。各位读者知道为什么可以以这种形式加以调用呢?这主要是因为,根据这个类创建的对象,只要成员变量采用了关键字static修饰,他们他们指向的都是同一个变量。即系统只为他们分配了一份存储空间。所以只通过类名就可以唯一的关联到这个静态的成员变量。而如果没有利用static关键字修饰的成员变量就不行。因为此时根据这个类创建的多个对象,其内部的成员变量是各自独立的,也就是说每个对象内部的成员变量都有一个对应的存储位置。所以说,如果一个类有多个对象,那么就不能够通过对象直接关联到变量对应的存储位置了。系统不知道这个类对应的对象到底是哪个,即存在一对多的情况。而采用了static关键字修饰的变量,无论有多少个对象,其都是一对一的关系。所以,可以通过类名.成员变量名的方式来直接引用这个成员变量。
虽然两种方法都可以实现对static变量的引用。但是笔者建议大家采用第二种方式。并不是说采用第二种方式更加的便捷或者说可以提高应用程序的性能。笔者这么建议,主要是从代码的阅读性上来考虑的。如果采用对象名.成员变量这种形式来引用的话,那么就不怎么直观的反应这个变量的特殊性。而如果采用类名.成员变量的形式来引用的话,那么成语员就可以一目了然的知道这个成员变量就是静态变量。这有利于代码的阅读与修改。
四、利用Static关键字来定义成员方法。
利用Static关键字来定义静态的成员方法,其实跟静态成员变量的定义类似。只需要在某个方法前面加上关键字static即可。不过在内部的实现机制上,两个还是有差别的。从以上的分析中可以看出,当将某个成员变量定义为静态变量时,其实内部数据创建的方式得到了改变。因为正常情况下,非静态成员变量每个对象都有一个存储空间,也就是说一个类如果有多少个对象则这个成员变量就有多少个存储空间。而如果成员变量设置为静态变量时,则一个类中的一个静态成员变量只有一个存储空间。即使这个类创建了数百个对象,但是这个对象中的静态成员变量也只有一个存储空间。这就是静态成员变量与非静态成员变量的主要差异。但是如果将某个方法定义为静态方法的话,差别就没有这么大。这主要是因为方法只涉及到调用,很少涉及到存储空间的分配。