最近,看到一道面试题,如下
class Class1 { private static int count = 0; static Class1() { count++; } public Class1() { count++; } } Class1 one = new Class1(); Class1 two = new Class1();
问程序执行完成以后,Class1.Count的值是多少。很显然,考查的是对static关键字的基本认识,答案是3。
从程序的执行顺序来说,第一次实例化类Class1时,先走静态构造函数==>普通无参构造函数,第一次实例化Class1后,count的值为2。
第二次实例化类Class1时,不会执行静态构造函数,直接走无参构造函数,执行完后,count的值变为3.
如果此题答案正确,那么请看下面的考题
class A { public static int X = B.Y; static A() { X++; } } class B { public static int Y=A.X; static B() { Y++; } }
请问 A.X=? B.Y=?
A.X表示此时开始访问A类,执行X=B.Y(此时先给其分配空间,并辅以0来初始化,然后调用对应的成员初始化语句来初始化这个静态成员);
B.Y表示开始访问B类,执行Y=A.X(此时不是第一次访问类型A,所以不再进行静态成员初始化和静态构造函数的调用),此时,系统默认A.X=0; 既然访问B类,就会执行B类的静态构造函数,B类的构造函数执行完毕,此时Y=1,
static int X=1,然后执行A类的静态构造函数,执行完毕后,X=2,因此A.X=2。
B.Y开始实例化B类。 但是B类的静态字段与静态构造函数已经执行了一次,不会再执行第二次A.X执行完毕后,Y已经等于1,因此B.Y=1。
因此,可以了解到静态字段以及静态构造函在类被实例化时的一些特殊点:
1、静态字段先于静态构造函数被初始化,静态构造函数在一个类中只有一个且不能带有参数;
2、静态成员初始化语句与静态构造函数在指定的程序域中只会被执行一次,不论这个类被实例化多少次;
3、对于存在多个static成员,他们的初始化将按照文本顺序进行,不会因为调用顺序而改变。
那么,静态构造函数什么时候会被首次触发呢?
1、该类的实例被创建;
2、任何一个static成员被引用。
class Class1 { private static Class1 obj = new Class1(); public static int counter1; public static int counter2 = 0; private Class1() { counter1++; counter2++; } public static Class1 getInstance() { return obj; } [STAThread] static void Main(string[] args) { Class1 obj = Class1.getInstance(); Console.WriteLine("Class1.counter1=="+Class1.counter1); Console.WriteLine("Class1.counter2=="+Class1.counter2); Console.Read(); } }
Design&Pattern 的 Singleton Pattern 的时候,因为静态初始化是在 .NET 中实现 Singleton 的首选方法。