Short answer: Java and C # do not avoid separate compilation; they make full use of it.
Where they differ from each other, they do not require the programmer to write a pair of separate header / implementation files when writing reusable libraries. The user writes the class definition once, and the compiler extracts information equivalent to the "header" from this single definition and includes it in the output file as "type metadata". Thus, the output file (a .jar , full of .class files in Java or a .dll assembly in .NET languages) is a combination of binary files and headers in one package.
Then, when another class is compiled and depends on the first class, it can look at the metadata instead of finding a separate include file.
It happens that they are aimed at a virtual machine, and not at a specific architecture of the chip, but this is a separate problem; they could put the x86 machine code as a binary file and still have header-like metadata in the same file (this is actually an option in .NET, although rarely used).
In C ++ compilers, they usually try to speed up compilation using "precompiled headers." The metadata in the .NET .dll and .class files is much like a pre-compiled header - it has already been analyzed and indexed, ready for quick search queries.
The result is that in these modern languages there is one way to perform modulation, and it has the characteristics of a beautifully organized and manually optimized C ++ modular assembly system - quite elegant, saying ASFAC ++ B.
Daniel Earwicker
source share