C#与Java实例化对象时的差异

来源:互联网 发布:8点法求解基础矩阵 编辑:程序博客网 时间:2024/06/07 23:48

先来看看一段Java代码:

package example;class Print {    public Print(String info) {        System.out.println("测试信息----" + info);    }}class BaseA {    private Print p = new Print("实例变量A");    private static Print p1 = new Print("静态变量A");    static {        System.out.println("BaseA静态块");    }    public BaseA() {        System.out.println("BaseA构造方法");    }    public void Invoke() {        System.out.append("Invoke----BaseA");    }}class BaseB extends BaseA {    private Print p = new Print("实例变量B");    private static Print p1 = new Print("静态变量B");    static {        System.out.println("BaseB静态块");    }    public BaseB() {        System.out.println("BaseB构造方法");    }    @Override    public void Invoke() {        System.out.append("Invoke----BaseB");    }}class BaseC extends BaseB {    private Print p = new Print("实例变量C");    private static Print p1 = new Print("静态变量C");    static {        System.out.println("BaseC静态块");    }    public BaseC() {        System.out.println("BaseC构造方法");    }    @Override    public void Invoke() {        System.out.append("Invoke----BaseC");    }}public class Test {    public static void main(String[] args) {        BaseC bc = new BaseC();        bc.Invoke();    }}run:测试信息----静态变量ABaseA静态块测试信息----静态变量BBaseB静态块测试信息----静态变量CBaseC静态块测试信息----实例变量ABaseA构造方法测试信息----实例变量BBaseB构造方法测试信息----实例变量CBaseC构造方法Invoke----BaseC成功构建 (总时间: 0 秒)

由此可见:Java在实例化对象的时候有几个规律

1、静态的肯定在前面:静态变量>静态块代码

2、总是从最底层的类开始实例化,从父类开始把所有静态的加载完,然后从父类开始把所有实例的东东加载完

 

执行顺序:

1.  初始化ParentClass的静态字段(按声明顺序)
2.  初始化ParentClass的静态块
3.  初始化ChildClass的静态字段(按声明顺序)

4.  初始化ChildClass的静态块

5.  初始化ParentClass的实例字段(按声明顺序)
6.  初始化ParentClass的构造方法
7.  初始化ChildClass的实例字段(按声明顺序)

8.  初始化ChildClass的构造方法


再来看看C#的代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{    class Print    {        public Print(string info)        {            Console.WriteLine("测试信息---" + info);        }    }    class BaseA    {        private Print p = new Print("实例变量A");        private static Print p1 = new Print("静态变量A");        static BaseA()        {            Console.WriteLine("静态构造方法A");        }        public BaseA()        {            Console.WriteLine("构造方法A");        }        public virtual void Invoke()        {            Console.WriteLine("Invoke---BaseA");        }    }    class BaseB : BaseA    {        private Print p = new Print("实例变量B");        private static Print p1 = new Print("静态变量B");        static BaseB()        {            Console.WriteLine("静态构造方法B");        }        public BaseB()        {            Console.WriteLine("构造方法B");        }        public override void Invoke()        {            Console.WriteLine("Invoke---BaseB");        }    }    class BaseC : BaseB    {        private Print p = new Print("实例变量C");        private static Print p1 = new Print("静态变量C");        static BaseC()        {            Console.WriteLine("静态构造方法C");        }        public BaseC()        {            Console.WriteLine("构造方法C");        }        public new void Invoke()        {            Console.WriteLine("Invoke---BaseC");        }    }    class Program    {        static void Main(string[] args)        {            BaseC bc = new BaseC();            bc.Invoke();        }    }}测试信息---静态变量C静态构造方法C测试信息---实例变量C测试信息---静态变量B静态构造方法B测试信息---实例变量B测试信息---静态变量A静态构造方法A测试信息---实例变量A构造方法A构造方法B构造方法CInvoke---BaseC

1、先静态的东东在前面,静态变量>静态构造方法

2、从子类到父类(非静态构造方法除外,确实从父类到子类,与Java一样);先子类的静态——>实例,在父类静态——>实例…………父类构造方法——>子类构造方法

 

执行顺序:

1.  初始化ChildClass的静态字段(按声明顺序)
 
2.  初始化ChildClass的静态构造函数
 
3.  初始化ChildClass的实例字段
 
4.  调用ChildClass的构造函数,并在此中断, 调用ParentClass的构造函数, 导致ParentClass开始初始化 
 
5.  初始化ParentClass的静态字段
 
6.  初始化ParentClass的静态构造函数
 
7.  初始化ParentClass的实例字段
 
8.  调用ParentClass的实例构造函数 
 
9.ParentClass初始化完毕, 调用ChildClass的构造函数,完成创建