有时你会想要定义一个类成员,其使用与任何对象都无关.通常,必须通过类的对象访问类成员,但是类可以创建无须引用指定的实例就可以单独使用的成员.要创建这样的成员,应该在他的声明之前添加关键字static,当一个成员声明为static后,可以在创建类的对象之前访问该成员,而无须引用任何对象.方法和变量都可以声明为static.最常用的static成员示例是main(),将main()声明为static是因为他必须在程序开始时由操作系统调用.在类以外使用static成员时,只需在点操作符之前指定类名即可,不需要创建对象,例如,如果想把10赋给一个名为count的static变量,该变量是Timer类的一部分,可以使用下面这行代码:
Timer.count = 10;
这种格式与通过对象访问普通实例变量相似,只不过使用的是类名.static方法能够以同样的方式被调用–通过在类名后使用点操作符.
声明为static的变量本质上都是全局变量.声明对象时,不生成static变量的副本.相反,类的所有实例共用一个static变量,下面的示例显示了static变量和实例变量之间的不同:
public class test2 { // @param args public static void main(String args[]) { StaticDemo ob1 = new StaticDemo(); StaticDemo ob2 = new StaticDemo(); ob1.x = 10; ob2.x = 20; System.out.println(" ob1.x : "+ob1.x+" ob2.x : "+ob2.x); //each object shares one copy of a static variable. System.out.println("set StaticDemo.y to 19 :"); StaticDemo.y = 19; System.out.println("ob1.sum() :"+ob1.sum()); System.out.println("ob2.sum() :"+ob2.sum()); System.out.println("set StaticDemo.y to 100 :"); StaticDemo.y = 100; System.out.println("ob1.sum() :"+ob1.sum()); System.out.println("ob2.sum() :"+ob2.sum()); } } class StaticDemo { int x; static int y; int sum() { return x + y; } }
输出:
ob1.x : 10 ob2.x : 20 set StaticDemo.y to 19 : ob1.sum() :29 ob2.sum() :39 set StaticDemo.y to 100 : ob1.sum() :110 ob2.sum() :120
如你所见,静态变量y被ob1和ob2共享.修改他会影响整个类,而不只是一个实例.
static方法和普通方法之间的区别就是static方法是通过类名调用的,不需要创建类的任何对象.你已经看到了这样的示例:sqrt()方法,他是Java的标准Math类的一个方法.下面是一个创建static方法的示例:
public class test2 { // @param args public static void main(String args[]) { System.out.println("val is "+StaticDemo.val); System.out.println("staticDemo.valDiv2(): "+StaticDemo.valDiv2()); StaticDemo.val = 4; System.out.println("val is "+StaticDemo.val); System.out.println("staticDemo.valDiv2(): "+StaticDemo.valDiv2()); } } class StaticDemo { static int val = 1024; static int valDiv2() { return val/2; } }
输出:
val is 1024 staticDemo.valDiv2(): 512 val is 4 staticDemo.valDiv2(): 2
声明为static方法存在以下几个限制:
他们只能直接调用其他static方法.
他们只能直接访问static数据.
他们没有this引用.
static代码块
有时类在创建对象之前,需要进行一些初始化.例如,可能需要建立与远程站点的连接.也可能需要在使用类的任何static方法之前,初始化某些static变量.为了处理这些情况,Java允许声明static代码块.static代码块在类的第一次被加载时执行,因此是在使用类之前执行的.
static代码块的示例如下所示:
public class test2 { // @param args public static void main(String args[]) { StaticDemo ob = new StaticDemo("Inside Constructor"); } } class StaticDemo { static int val; static { System.out.println("Inside static block."); val = 1024; } StaticDemo(String msg) { System.out.println(msg); } }
输出:
Inside static block. Inside Constructor
如你所见,static代码块可以在构造任何对象之前执行.