理解static关键字

有时你会想要定义一个类成员,其使用与任何对象都无关.通常,必须通过类的对象访问类成员,但是类可以创建无须引用指定的实例就可以单独使用的成员.要创建这样的成员,应该在他的声明之前添加关键字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代码块可以在构造任何对象之前执行.