菜鸟瞎扯――对象的创建过程

晚上随便扯扯对象的创建过程,加深一下理解。主要是关于类实例化时字段的初始化过程。

示例代码如下:
    public class Class1
    
{
        
private int myInt1;  //断点1
        private int myInt2 = 10;
        
private string myStr1;
        
private readonly string myStr2;
        
private readonly string myStr3 = "Hello";
        
public static int myInt3;
        
public static int myInt4 = 100;
        
private const int MY_CONST = 5;

        
public Class1()  //断点2
        {
            myInt1 
= 20;
            myStr2 
= "World";
            myStr3 
= "China";
        }

    }


    
public class App
    
{
        
public static void Main(string[] args)
        
{
            
int a = 10;  //断点3
            Method();
        }

        Public 
static void Method()
        
{
            Class1 c1 
= new Class1();  //断点4
            Class1 c2 = new Class1();  //断点5
        }

    }


这里主要是通过加断点调试来看Class1这个类的实例化过程,现在,按下调试按钮:
可以看到,指针指在了断点3处,如下图:



此时,局部变量a的值为0,它即将要被赋以10。此时在Watch中Watch一下Class1,会发现常量MY_CONST和静态字段myInt3、myInt4都已经有了值,并且是声明时我们给它赋的那个值,而myInt3因为声明时没有赋值,所以有了默认的0(因为它们是int类型)。对于这个问题,就用《.net本质论》中的几句话来解释吧:

CLR会给static 字段分配一次内存:即在类型被首次加载的时候……类型被首次使用之前(静态字段的)内存会被分配和初始化,对于其它字段(指非静态、非常量字段),每当新的实例被分配在堆上时,内存都会被分配和初始化……常量值是在编译时计算的。

PS: 当我们点下调试按钮时,如果注意VS下方的状态栏的话,会发现先是Building…然后Build Success,然后才启动调试,有时候这些IDE做得太自动化了可能很空易就让我这样的菜鸟忽略了这一点。注意,源代码是先编译成MSIL,然后我们再去对着生成的exe来调试的,所以在编译完,启动调试前,MY_CONST的值就已经确定了。

回头看,断点1早已自动往下移了一行(调试一启动它就移到那了)。然后点两下step over,黄箭头进入了Method()中,指在“断点4”,再点一次就跳到了“断点1”的下一行,此时c1所有字段都已用默认值初始化(包括静态字段),如下图:



再点一次step over,黄色箭头指向了下图所示位置:



此时myInt2已有了值10,这说明:当用new实例化类时,所有的字段都被初始化,如果在声明字段时有对其赋值,如程序段中的private int myInt2 = 10;那么,这个赋值过程就发生在用默认值初始化字段的下一步。

继续点step over,黄箭头指在了断点2处,此时myStr3已经有了”Hello”值,再继续step over,构造方法中的语句将被依次执行,我们会看到,在构造方法中对myStr3这个readonly字段进行了重新赋值(如果在构造方法中还不给他赋值,那它就只好一辈子用0这个默认值了,在构造方法中对其赋值是其能被赋值的最后机会)。

然后回到Method方法中的“断点4”处,此时状态如下图:



可以看到,c2虽然还没有被实例化,但是它的静态字段myInt4已经有值100了,其实不能这么说,myInt4不能算是c2的,而是属于类型Class1的,它在类型首次被加载时就分配内存,初始化,静态字段的内存分配只进行一次。

本人水平有限,以上言论也还没有经过权威机构认证,如果大家发现其中有说错了的地方,还请指点一下小弟,3Q VM。
posted @ 2008-05-09 02:39  水言木  阅读(510)  评论(1编辑  收藏  举报