之前经常遇到此类问题,虽然知道他们的区别和用法,但在一起用时总是在不经意间出点儿错,所以特总结如下:
先上简单测试代码:
package test01;
public class TestStatic {
public static int a = 1;//静态变量
public String b = "a";//非静态变量
static {//静态块
a = 2;
}
public TestStatic() {
a = 6;
b = "d";
}
{//非静态块
a = 3;
b = "b";
}
public static void main(String[] args) {
System.out.println(TestStatic.a); //4
System.out.println(new TestStatic().b); //d
System.out.println(TestStatic.a); //6
}
static {//静态块
a = 4;
}
{//非静态块
a = 5;
b = "c";
}
}
上述代码输入结果是:4 d 6
静态变量的定义及静态块在类加载时执行且仅执行一次,其执行的顺序按代码中定义的顺序执行,静态变量、静态块、静态方法是属于类的;
而非静态变量、非静态块、非静态方法则属于类实例的,注意非静态块是在实例化之前先执行的,之后才会执行构造函数内的代码。
执行顺序可以简单记为:静态区-->非静态区-->构造方法-->使用对象...(唯一需重点注意的是静态区代码仅在该类被加载时执行一次,之后无论该类被实例化多少次,静态区代码都不会再执行!)
区分开这些之后,对于他们的用法就容易操作了:
静态区,非静态区,构造方法都可以对变量进行初始化,具体使用哪一种要看应用场景而定,择取一个更适合的去使用。
经常静态区要去执行一些诸如加载资源之类的代码,静态变量属于类,所有该类的实例都可以对其进行访问和操作,每一个实例对同一个静态变量进行的操作都会影响到其他实例访问的该静态变量,所以对于多线程编程中,要谨慎处理,避免触发线程安全问题!