编译循环依赖是如何工作的?

Posted

技术标签:

【中文标题】编译循环依赖是如何工作的?【英文标题】:How does compiling circular dependencies work? 【发布时间】:2011-03-03 06:01:05 【问题描述】:

我已经用 Java 制作了示例,但我认为(未经测试)它适用于其他(所有?)语言。

您有 2 个文件。一、M.java

public class MType 
    XType x;
    MType() x = null;

第二,另一个文件(在同一目录下),XType.java

public class XType 
   MType m;
   public XType(MType m) this.m = m;

好吧,这是糟糕的编程,但如果你运行javac XType,它会编译:甚至MType 也会编译,因为XType 需要它。但是... MType 需要XType ... 它是如何工作的?编译器如何知道发生了什么?

我想知道编译器(javac 或您知道的任何其他编译器)如何管理这种情况,而不是如何避免这种情况。

我问这个问题是因为我正在编写一个预编译器并且我想处理这种情况。

【问题讨论】:

【参考方案1】:

您需要采取 2-pass 或multi-pass 方法:

像 Java 这样的语言需要一个多遍编译器,因为 x 的定义不需要在使用之前出现:

public class Example   
public static void main(String [] args) 
    assert(x==0);           
    x++;
    assert(x==1);

static int x=0;

有多种方法,例如您可以执行以下操作:

第一遍可以查找所有变量声明,第二遍查找方法声明等,直到最后一遍使用所有这些信息来编译最终代码。

【讨论】:

那么当它编译第二个文件时,编译器已经知道第一个是什么了? @Fabio - 编译器的每一轮都会处理所有文件,收集下一轮所需的信息。【参考方案2】:

第一个文件不需要知道关于 XType 的任何信息,除了它是一个类型,第二个文件中的 MType 也是如此。此外,在 Java 中,所有对象实际上都具有相同的大小(因为所有内容都是通过引用访问的),因此不需要对象的大小。在其他语言中情况并非如此 - 例如,您的代码不会在 C++ 中编译(语言语法除外)。

【讨论】:

但是如果使用XType的方法呢?它必须知道 Xtype 的方法.. 不是吗? 另外,我不确定您所说的“所有对象实际上大小相同”是什么意思。 他指的是(例如)m 持有一个引用,并且所有引用都具有相同的大小。但这不是类型所需的唯一信息。还需要了解其成员以及有关其超类型层次结构的大量信息。

以上是关于编译循环依赖是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

深谈Spring如何解决Bean的循环依赖

MyBatis工作原理及循环依赖

golang中包循环依赖问题

架构案例-依赖倒置循环依赖解耦

架构案例-依赖倒置循环依赖解耦

架构案例-依赖倒置循环依赖解耦