为什么以下案例的执行流程不同?

时间:2017-02-15 16:55:27

标签: java c# oop object

有人可以详细说明以下情况,如果解释包括内存分配及其对三种情况的参考,会更方便:

  1. 如何在三种情况下执行流程?
  2. 为什么三种情况下流量不同?
  3. 虽然这两个类之间存在循环依赖关系,但为什么单独使用案例1会导致其余案例失败?
  4. CASE ONE

    namespace CircularDependency_1
    {
        class Program
        {
            static void Main(string[] args)
            {
                A a = new A();
                Console.WriteLine("executed");
                Console.ReadLine();
            }
        }
    
        public class B
        {
            public static A a = new A();
    
            public B()
            {
    
                Console.WriteLine("Creating B");
            }
        }
    
        public class A
        {
            public static B  b = new B();
    
            public A()
            {          
                Console.WriteLine("Creating A");
            }
        }
    }
    

    输出

    Creating A
    Creating B
    Creating A
    executed
    

    案例二

    namespace CircularDependency_1
    {
        class Program
        {
            static void Main(string[] args)
            {
                A a = new A();
                Console.WriteLine("executed");
                Console.ReadLine();
            }
        }
    
        public class B
        {
            public static A a;
    
            public B()
            {
                a = new A();
                Console.WriteLine("Creating B");
            }
        }
    
        public class A
        {
            public static B b;
    
            public A()
            {      
                 b = new B();
                Console.WriteLine("Creating A");
            }
        }
    }
    

    输出 由于StackOverflowException,进程终止。

    案例三

    namespace CircularDependency_1
    {
        class Program
        {
            static void Main(string[] args)
            {
                A a = new A();
                Console.WriteLine("executed");
                Console.ReadLine();
            }
        }
    
        public class B
        {
            public A a;
    
            public B()
            {
                a = new A();
                Console.WriteLine("Creating B");
            }
        }
    
        public class A
        {
            public B b;
    
            public A()
            {      
                 b = new B();
                Console.WriteLine("Creating A");
            }
        }
    }
    

    输出 由于StackOverflowException,进程终止。

2 个答案:

答案 0 :(得分:2)

@Versatile,你很亲密,但不对。第一种情况执行而另外两种情况失败的原因不仅仅是因为对象是在构造函数内部创建的,还是在类内部(在构造函数外部)创建的。为了证明这一点,请尝试分别在ab类(案例一)中使BA字段不是静态的;并且你会发现它会失败,即使这些对象是在构造函数之外创建的。

案例2和3由于@Versatile解释的原因而失败。 案例1由于static成员而执行。 让我们来看看流程:

Main方法中,行A a = new A()开始创建a对象。在此过程中,由于行B,将创建类public static B b = new B()的对象 - 由于行{{1},此行将开始创建类A的另一个对象在类public static A a = new A()的主体中。现在,这里出现了魔法(不会引发循环依赖)。这一行B将开始创建另一个类public static A a = new A()的对象,而创建此对象时,它不会创建另一个类A的对象,因为它是{{B的静态成员1}},它已经创建了。众所周知,类的静态成员在类的所有实例之间共享。因此,它不会触发创建另一个类A的对象。总的来说,我们最终会按顺序排列三个类:BAB

<强>更新

有趣的是,在第一种情况下,如果我们在构造函数中初始化静态成员会发生什么。即使AA类声明了静态成员,执行也会因循环依赖而失败。这是因为在执行构造函数之前不会初始化静态成员。

答案 1 :(得分:1)

1.如何在三种情况下执行流程? 首先调用静态void Main(),然后调用对象A的构造函数,因为代码行public class A { public static B b = new B(); }

2.为什么三种情况下的流量不同?

3.虽然两个类之间存在循环依赖关系,但为什么单独使用案例1会导致其余案例失败?

出于同样的原因,观察到上述两种情况。如果仔细观察,可按如下方式分配内存。 类中的Case1而不是构造函数。即

 def wordeasy3_label(label):
    def wordeasy3():
        global i
        if i != 3: 
            label.config(text=(list[i]))
            label.place(x=0,y=0)
            i+=1
            label.after(2000, wordeasy3)
        else:
            label.destroy()
    wordeasy3()

此外,该对象是静态的,因此它只会创建一次,并且一旦在同一行中分配的内存只执行一次,就会创建它。

情况2和情况3:对象A和B的内存在构造函数中分配,即在A的构造函数中,内存分配给B,B内存的构造函数分配给A,这导致调用相应的类构造函数一次又一次,直到它抛出异常。