四、static 1.static修饰符 static修饰符能够与属性、方法和内部类一起使用,表示是“静态”的。 类中的静态变量和静态方法能够与“类名”一起使用,不需要创建一个类的对象来访问该类的静态成员。所以static修饰的变量又称作“类变量”。这与实例变量不同。实例变量总是用对象来访问,因为它们的值在对象和对象之间有所不同。 下列示例展示了如何访问一个类的静态变量: class StaticModifier { staticinti = 10; int j; StaticModifier() { j = 20; } } publicclass Test { publicstaticvoid main(String args[]) { System.out.println("类变量 i=" + StaticModifier.i); StaticModifier s = new StaticModifier(); System.out.println("实例变量 j=" + s.j); } } 上述程序的输出是: 类变量i=10 实例变量j=20 2.static属性的内存分配 在上面的例子中,无需创建类的对象即可访问静态变量i。之所以会产生这样的结果,是因为编译器只为整个类创建了一个静态变量的副本,因此它能够用类名进行访问。也就是说:一个类中,一个static变量只会有一个内存空间,虽然有多个类实例,但这些类实例中的这个static变量会共享同一个内存空间。记住:static只存一份。 示例如下: publicclass Test{ static UserModel um = new UserModel(); publicstaticvoid main(String[] args) { Test t1 = new Test(); t1.um.userName = "张三"; Test t2 = new Test(); t2.um.userName = "李四"; System.out.println("t1.um.userName=="+t1.um.userName); System.out.println("t2.um.userName=="+t2.um.userName); } } class UserModel{ public String userName=""; } 运行结果: t1.um.userName==李四 t2.um.userName==李四 为什么会是一样的值呢?就是因为多个实例中的静态变量um是共享同一内存空间, t1.um和t2.um其实指向的都是同一个内存空间,所以就得到上面的结果了。 要想看看是不是static导致这样的结果,你可以尝试去掉UserModel前面的static,然后再试一试,看看结果,应该如下: t1.um.userName==张三 t2.um.userName==李四 还有一点也很重要:static的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static变量,它都会被初始化。 小结一下:类变量(class variables)用关键字static修饰,在类加载的时候,分配类变量的内存,以后在生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其它对象。外部有两种访问方式:通过对象来访问或通过类名来访问。 3.static的基本规则 有关静态变量或方法的一些要点如下: l 一个类的静态方法只能访问静态属性 l 一个类的静态方法不能够直接调用非静态方法 l 如访问控制权限允许,static属性和方法可以使用对象名加‘.’方式调用;当然也可以使用实例加‘.’方式调用 l 静态方法中不存在当前对象,因而不能使用“this”,当然也不能使用”super”; l 静态方法不能被非静态方法覆盖; l 构造方法不允许声明为static的 static方法可以用类名而不是引用来访问,如: public class GeneralFunction { public static int addUp(int x, int y) { return x + y; } } public class UseGeneral { public void method() { int a = 9; int b = 10; int c = GeneralFunction.addUp(a, b); System.out.println("addUp() gives " + c); } } 因为static方法不需它所属的类的任何实例就会被调用,因此没有this值。结果是,static方法不能访问与它本身的参数以及static变量之外的任何变量,访问非静态变量的尝试会引起编译错误。 注:非静态变量只限于实例,并只能通过实例引用被访问。 4.静态初始器——静态块 4.1什么是静态初始器? 静态初始化器(Static Initializer)是一个存在与类中方法外面的静态块。静态初始器仅仅在类装载的时候(第一次使用类的时候)执行一次。 静态初始化器的功能是:往往用来初始化静态的类属性。 4.2示例 class Count { publicstaticintcounter; static {//只运行一次 counter = 123; System.out.println("Now in static block."); } publicvoid test(){ System.out.println("test method=="+counter); } } publicclass Test { publicstaticvoid main(String args[]) { System.out.println("counter=" + Count.counter); new Count().test(); } } 运行结果是: Now in static block. counter=123 test method==123
5.静态import 当我们要获取一个随机数时,写法是: publicclass Test { publicstaticvoid main(String[] args) { double randomNum = Math.random(); System.out.println("the randomNum=="+randomNum); } } 从JDK5.0开始可以写为: importstatic java.lang.Math.random; publicclass Test { publicstaticvoid main(String[] args) { double randomNum = random(); System.out.println("the randomNum=="+randomNum); } } 静态引用使我们可以象调用本地方法一样调用一个引入的方法,当我们需要引入同一个类的多个方法时,只需写为“import static java.lang.Math.*”即可。这样的引用方式对于枚举也同样有效。 Java私塾跟我学系列——JAVA篇 网址:http://www.javass.cn 电话:010-68434236 |