Compilers + interclass references: how does javac quickly execute C ++ compilers?

enter a description of the link here How does the java compiler manage to quickly resolve interclass links if you have a bunch of classes that all relate to each other and use other methods?

I know how C ++ compilers work in this regard: each .cpp file is compiled separately, and they use these terrible .h files to declare class fields / methods, so the same set of files and / or compilers must support precompiled headers.

But Java does not, and there is no separation in the software source of the class interfaces / implementations, as Turbo Pascal disabled.

I see that if you have the Foo class and it belongs to the Bar, Baz, Quux classes, which are in a separate barbazquux.jar file, then everything will be simple: the .jar file is already compiled, so when Foo.java is compiled, it can just look at the .class files in barbazquux.jar.

But if you have circular references to classes, and the Foo class refers to the Bar class, which refers to the Foo class, how can it compile Foo.java without having to compile Bar.java first, and then decide that it should compile Foo.java and get stuck in the loop?

What does the Java compiler do to handle references between classes?


edit: yair points out another question with answers vaguely mentioned by multipass compilers. Good, so there are a few passes. What exactly happens on each pass and how does Java manage to compile so fast? Do I need to sort out each file in each pass or store an abstract syntax tree to save time or what?

+6
source share
2 answers

C ++ should parse the source code of an outer class declaration, usually in an .hpp file. Java processes the object code of external class declarations that has already been compiled. What Java does is more like languages ​​with packages, for example. Ada, Modula-3, ... That's why most C / C ++ compilers also have "precompiled headers."

0
source

C ++ grammar is much more complicated, the details of the expression are ambiguous. Thus, Javac is more effective at analysis. C ++ also has finer-grained compilation units. C ++ includes, even if precompiled, has recursive visibility: includes includes the definition of names that can be used. In Java, if you use the parent class of the imported class, you need to explicitly import it.

References to cyclic classes are problematic. In Java, you can predict the assumption that a class exists even if that class has not yet been compiled. But the java compiler is even more impressive, being able to compile them at the same time. The same thing because of cyclic dependencies. JVM byte code calls commands using method names, so you can bundle the first class with a class.

public class A { public static void a(int i) { System.out.println("a(" + i + ")"); if (i < 10) Bb(i + 2); } } public class B { public static void b(int i) { System.out.println("b(" + i + ")"); if (i < 10) Aa(i + 1); } } public static void main(String... args) { Bb(0); } 
-1
source

Source: https://habr.com/ru/post/908241/


All Articles