我有一个非常大的 Java 项目,其中有很多类和方法。
我在 Wikipedia 上读到“像 Java 这样的语言需要多遍编译器,因为 x 的定义不需要在使用之前出现”。如果我使用 c/c++ 规则构建代码,以便类中的所有方法在类代码中使用之前都进行声明,这会加快编译过程(与使用后定义的所有方法相比)吗?它不必在编译期间执行额外的操作?如果属实,那么如果在使用之前在代码中只定义部分方法(相对于使用之后定义的所有方法),是否也会加快编译速度?
我知道可读性/维护应该放在第一位,但只考虑我的问题的性能影响。
简而言之,不,没有什么可期待的好处。
Java 编译器甚至不会尝试执行单遍处理,因此您的代码安排是否允许它并不重要。
C 编程语言仅具有全局函数,这使得可以轻松推理特定代码位置处定义的函数集。
相比之下,Java根本没有全局函数。上下文特定的解析包括在与调用者相同的类中声明的方法(您想到的)、从超类或接口继承的方法、在外部类中声明的方法、由外部类继承的方法以及通过
import static
声明。
此外,与 C 不同,Java 支持方法重载。因此,对于方法的解析,仅仅找到一个适用的方法是不够的,Java语言要求编译器找到“最具体”的方法。因此,即使调用者上方有匹配的方法声明,编译器也必须检查调用者下方是否有更具体的方法或从超类继承的方法。 换句话说,调用解析为同一源文件中调用之前的最具体方法的情况是一种罕见的极端情况,没有编译器供应商会尝试优化。
虽然细节取决于实现,但您可以预期处理基本上如您在问题中链接的维基百科文章中所描述的那样。首先,在语法分析过程中构建一个
抽象语法树,然后,语义分析和代码生成将对该数据结构进行操作。单次传递必须以不同的方式工作,因此,需要维护替代实现,但没有任何好处,因为它不适用于现实生活中的情况。
为了更多地说明在句法分析之后进行语义分析的要求,请考虑以下示例:System.out.println("hello world");
虽然该语句的目的对于读者来说是显而易见的,但对于编译器来说却不是:
可能有一个变量
System
out
,其类型有一个println
方法。可能有一个变量 System
out
和静态 println
方法。可能有一个类型 System
out
,其类型具有 println
方法。 (宾果游戏)可能有一个类型 System.out
println
方法。
System
的变量(包括继承的成员变量)。即使没有,编译器也必须在本地和嵌套作用域以及当前包中检查类
System
,因为从 java.lang
隐式导入的类具有最低优先级。因此,即使是 hello-world 示例也不允许一次性编译。