在使用Java一段时间后,我总是按照以下顺序设计我的类:声明变量,构造函数,然后是方法。我从来没有想过这一点,直到我遇到了编译得很好的代码:
public class Main {
int m1(){
return ++i;
}
int i=10;
}
我的问题是它是如何工作的?意思是当编译器开始编译此代码时,它应该从上到下开始,对吗?那么它怎么知道variable i
代表什么,它的价值是什么呢?"它无法展望未来",用愚蠢的方式说。
有人可以告诉我这是如何工作的吗?我唯一的猜测是编译器首先编译变量,然后编译构造函数/方法(无论我的源代码顺序如何)。但是我没有遇到任何参考/文档,所以不想做出盲目的假设。
这是有效的,因为编译是通过多个步骤完成的。
第一步是解析。当编译器解析示例代码时,它会"注意"存在标识符i
的用法,并且有一个恰好具有名称i
的变量的声明。基于此信息(和一组规则),编译器匹配标识符声明和标识符用法(例如,构造符号表)。
检查标识符是否具有正确的用法类型称为类型检查,将在后面的步骤中完成。
因此,当编译器"提出"诸如"识别器i
代表什么?"之类的问题时,它已经从解析步骤中得到了答案。
在运行时之前,可能无法确定变量的值(例如,如果值是由用户输入的)。但是,如果可以在编译时确定该值,则可以将其用于优化,例如常量传播,这是编译过程中的后续步骤之一。