在 Java 中如何引用在方法之后声明的变量?

How does referencing a variable declared AFTER a method work in Java?

在使用 Java 一段时间后,我总是按照以下顺序设计我的 class:声明变量、构造函数,然后是方法。我从来没有想过这个,直到我遇到编译得很好的代码:

public class Main {

int m1(){
    return ++i;
}

int i=10;

}

我的问题是它是如何工作的?意思是compiler开始编译这段代码的时候,应该是从top to bottom开始,对吧?那么它怎么知道 variable i 代表什么以及它的值是什么? “它不能展望未来”,用愚蠢的方式来说。

谁能告诉我这是怎么回事?我唯一的猜测是编译器首先编译变量,然后 constructor/methods (无论我的源代码顺序如何)。但是我还没有遇到任何reference/doc,所以不想盲目假设。

之所以可行,是因为编译是在 multiple steps 中完成的。

第一步是 parsing. When the compiler parses the example code, it "notes" that there is a usage of an identifier i and there is a declaration of a variable that happens to have the name i. Based on this information (and a set of rules) the compiler matches identifier declarations and identifier usages (and constructs a symbol table,例如)。

检查标识符是否具有正确的使用类型称为类型检查,并在 later step.

中完成

因此,当编译器“询问”诸如“标识符 i 代表什么?”之类的问题时,它已经从解析步骤中得到了答案。

在 运行 之前可能无法确定变量的值(例如,如果值由用户输入)。但是如果这个值可以在编译时确定,那么它可以用于优化,例如constant propagation,这是编译过程中的后期步骤之一。