【问题标题】:Why the flow of execution of the following cases was different?为什么以下案件的执行流程不同?
【发布时间】:2017-07-04 11:27:37
【问题描述】:

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

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

案例一

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 而终止。

【问题讨论】:

标签: java c# oop object


【解决方案1】:

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

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

Main 方法中,A a = new A() 行开始创建a 对象。在这个过程中,将创建一个类 B 的对象,因为 public static B b = new B() 行 - 由于 @987654333 类的主体中的 public static A a = new A() 行,这一行将开始创建类 A 的另一个对象@。现在,魔法来了(它不会触发循环依赖)。这行,public static A a = new A() 将开始创建另一个类 A 的对象,在创建这个对象时它不会创建另一个类 B 的对象,因为它是 A 的静态成员,并且它已经被创建了。众所周知,类的静态成员在类的所有实例之间共享。因此,它不会触发类B 的另一个对象的创建。总的来说,我们最终得到了三个类的实例:ABA

更新

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

【讨论】:

  • 感谢您指出这一点。我假设 static 的使用很明显,该对象只会被创建一次,而且因为它在该行被分配了新内存,因此它不会进入递归调用。
【解决方案2】:

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

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

3.虽然两个类之间存在循环依赖关系,但为什么单独执行案例 1 而其余案例都失败了?

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

public class A
{
    public static B  b = new B();
}

此外,该对象是静态的,因此它只会被创建一次,因为它是在同一行中分配的内存仅执行一次时创建的。

案例 2 和案例 3:在构造函数中将内存分配给对象 A 和 B一次又一次,直到抛出异常。

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多