静态变量初始化顺序
1.简单规则
首先先看一段最普遍的JAVA代码:
public class Test
{
public static Test1 t = new Test1();
public static int a = 0;
public static int b;
public static void main(String[] arg)
{
System.out.println(Test.a);
System.out.println(Test.b);
}
}
class Test1
{
public Test1()
{
Test.a++;
Test.b++;
}
}
这里先猜下控制台输出结果是什么?
OK, 或许你已经猜到下面了结果了,那么你还是熟悉Java的。
Java静态变量初始化遵循以下规则:
看了这个就会明白,原来Test.a的值变化了三次。
声明时设置为0>>Test1::Test1里设置为1>>Test.a初始化为0
2.复杂规则
明白了这个,请再看下面的代码。
public class A
{
public static int b = B.a;
public static A plus =new A(\"A\");
public static final int finalInt = (int)(Math.random()*100);
public static B p = new B(\"A\");
public static final String finalStr = \"finalStr\";
public static final Integer finalInteger = new Integer(10);
public static int a = 1;
public static B c = null;
public A(String from)
{
System.out.println(\"----------- begin A::A ----------------\");
System.out.println(\"A::A, from=\"+from);
System.out.println(\"A::A, A.b=\"+A.b);
System.out.println(\"A::A, A.finalInt=\"+A.finalInt);
System.out.println(\"A::A, B.a=\"+B.a);
System.out.println(\"A::A, B.plus=\"+B.plus);
System.out.println(\"----------- end A::A ----------------\");
}
public static void main(String[] arg)
{
System.out.println(\"main, A.b=\"+A.b);
System.out.println(\"main, B.t=\"+B.t);
System.out.println(\"main, C.a=\"+C.a);
}
}
class B
{
public static int t = A.a;
public static A plus = new A(\"B\");
public static int a = 1;
public B(String from)
{
System.out.println(\"----------- begin B::B ----------------\");
System.out.println(\"B::B, from=\"+from);
System.out.println(\"B::B, B.a=\"+B.a);
System.out.println(\"B::B, A.a=\"+A.a);
System.out.println(\"B::B, A.p=\"+A.p);
System.out.println(\"B::B, A.plus=\"+A.plus);
System.out.println(\"B::B, A.finalInt=\"+A.finalInt);
System.out.println(\"B::B, A.finalInteger=\"+A.finalInteger);
System.out.println(\"B::B, A.finalStr=\"+A.finalStr);
System.out.println(\"----------- end B::B ----------------\");
}
}
class C
{
public static final A a = new A(\"C\");
}
这个你还能猜到输出结果吗? 我是在一边测试一边写的,所以我没猜出来.哈哈
控制台输出结果为:
----------- begin A::A ---------------- A::A, from=B A::A, A.b=0 A::A, A.finalInt=0 A::A, B.a=0 A::A, B.plus=null ----------- end A::A ---------------- ----------- begin A::A ---------------- A::A, from=A A::A, A.b=1 A::A, A.finalInt=0 A::A, B.a=1 A::A, B.plus=A@a90653 ----------- end A::A ---------------- ----------- begin B::B ---------------- B::B, from=A B::B, B.a=1 B::B, A.a=0 B::B, A.p=null B::B, A.plus=A@1fb8ee3 B::B, A.finalInt=61 B::B, A.finalInteger=null B::B, A.finalStr=finalStr ----------- end B::B ---------------- main, A.b=1 main, B.t=0 ----------- begin A::A ---------------- A::A, from=C A::A, A.b=1 A::A, A.finalInt=61 A::A, B.a=1 A::A, B.plus=A@a90653 ----------- end A::A ---------------- main, C.a=A@61de33
这个结果你没猜到吧,哈哈.
要一句一句的讲解程序执行结果,还是要很到的篇幅的.这里就直接写出Java静态变量初始化遵循的规则了。
第一段的规则依然有效,只是不健全。
static数据的初始化
加上static限定的字段,是所谓的类字段,也就是说这个字段的拥有者不是对象而是类。无论创建多少对象,static数据都只有一份。
类内总是先初始化static字段,再初始化一般字段。接着初始化构造器。但是如果不创建这个类的对象,那这个对象是不会进行初始化的,并且只执行一次。
如下面的代码,在StaticInitialization类中,先初始化static Table table = new Table();,然后才去初始化Table对象,不然是不会被初始化的。
class Bowl {
Bowl(int marker) {
print(\"Bowl(\" + marker + \")\");
}
void f1(int marker) {
print(\"f1(\" + marker + \")\");
}
}
class Table {
static Bowl bowl1 = new Bowl(1);
Table() {
print(\"Table()\");
bowl2.f1(1);
}
void f2(int marker) {
print(\"f2(\" + marker + \")\");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard {
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard() {
print(\"Cupboard()\");
bowl4.f1(2);
}
void f3(int marker) {
print(\"f3(\" + marker + \")\");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String[] args) {
print(\"Creating new Cupboard() in main\");
new Cupboard();
print(\"Creating new Cupboard() in main\");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
输出:
Bowl(1) Bowl(2) Table() f1(1) Bowl(4) Bowl(5) Bowl(3) Cupboard() f1(2) Creating new Cupboard() in main Bowl(3) Cupboard() f1(2) Creating new Cupboard() in main Bowl(3) Cupboard() f1(2) f2(1) f3(1)
显示的静态初始化(也就是静态块)
把多个初始化语句包在一个static花括号里,叫做静态块,其实就是把多个static合在一起写了,本质是一样的。只有首次创建对象或者首次访问类的字段时才会执行,而且仅仅一次。
class Cup {
Cup(int marker) {
print(\"Cup(\" + marker + \")\");
}
void f(int marker) {
print(\"f(\" + marker + \")\");
}
}
class Cups {
static Cup cup1;
static Cup cup2;
static {
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups() {
print(\"Cups()\");
}
}
public class ExplicitStatic {
public static void main(String[] args) {
print(\"Inside main()\");
Cups.cup1.f(99); // (1)
}
// static Cups cups1 = new Cups(); // (2)
// static Cups cups2 = new Cups(); // (2)
}
输出:
Inside main() Cup(1) Cup(2) f(99)
非静态实例初始化
这个没什么好讲的,就是普通初始化,按顺序执行,可以多次执行。
class Mug {
Mug(int marker) {
print(\"Mug(\" + marker + \")\");
}
void f(int marker) {
print(\"f(\" + marker + \")\");
}
}
public class Mugs {
Mug mug1;
Mug mug2;
{
mug1 = new Mug(1);
mug2 = new Mug(2);
print(\"mug1 & mug2 initialized\");
}
Mugs() {
print(\"Mugs()\");
}
Mugs(int i) {
print(\"Mugs(int)\");
}
public static void main(String[] args) {
print(\"Inside main()\");
new Mugs();
print(\"new Mugs() completed\");
new Mugs(1);
print(\"new Mugs(1) completed\");
}
}
Inside main() Mug(1) Mug(2) mug1 & mug2 initialized Mugs() new Mugs() completed Mug(1) Mug(2) mug1 & mug2 initialized Mugs(int) new Mugs(1) completed
本文地址:https://www.stayed.cn/item/23564
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我