Static关键字的使用
static关键字用来定义静态数据,可用于所有对象中,并且不同对象数据可以互通,我们来看以下一个简单的例子。
public class Test {
public static int num = 1;
public void add(){
num++;
System.out.println("num="+num);
}
public static void main(String[] args) {
Test t1 = new Test();
t1.add();
Test t2 = new Test();
t2.add();
}
}
输出结果如下:
为了探究其原因,我们来看下以下代码:
public class Test {
public String test1;
public static String test2;
public void t1(){
System.out.println(test1);
System.out.println(test2);
}
public static void t2(){
System.out.println(test1);//编译报错
System.out.println(test2);
}
}
我们定义了一个普通变量和一个静态变量以及一个普通方法和一个静态方法,如图显示,普通方法可以随意的调用普通变量和静态变量,静态方法也可以调用静态变量,但当静态方法调用普通变量的时候则会报错。
如果需要能够调用则需要做以下处理。
public static void t2(){
// System.out.println(test1);//编译报错
Test test = new Test();
System.out.println(test.test1);
System.out.println(test2);
}
为了探究这一现象形成的原因,可以做以下尝试。
类加载
我们可以将一个类分为匿名代码块,静态代码块,构造方法三部分,并且初始化这个类,以此来查看类在加载的过程中对不同部分的处理顺序。
public class Test {
{
System.out.println("匿名代码块");
}
static{
System.out.println("静态代码块");
}
public Test(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Test test = new Test();
}
}
输出结果如下:
由此可知当一个类加载的时候首先加载的是静态代码块,然后才会加载匿名代码块和构造方法。为了更进一步理解为什么静态方法一开始不能调用普通变量,而创建对象后就可以调用了,可以做以下尝试。
public class Test {
{
System.out.println("匿名代码块");
}
static{
System.out.println("静态代码块");
}
public Test(){
System.out.println("构造方法");
}
public static void main(String[] args) {
System.out.println("~~~~~~~~~~~~~~~~");
Test test1 = new Test();
System.out.println("~~~~~~~~~~~~~~~~");
Test test2 = new Test();
}
}
得到的结果如下图:
显而易见,静态代码块只会在开始的时候执行一次,此时普通变量并没有被加载,因此静态方法无法使用普通变量,而随着对象的创建,普通变量逐渐被加载了,此时静态方法便可以调用普通变量了。
而正是因为静态代码区只会在开始调用一次,而其他模块会在每次创建对象的时候调用一次,因此不同对象操作的静态数据是同一份,所以数据互通。