java编译器如何解析非导入的名称



考虑我在java编译单元中使用来自包foo.bar的类型X,并且X不是在编译单元本身中定义的,也不是直接导入的。如何一个java编译器解决X现在有效?X可能存在以下几种情况:

  1. X可以通过星形导入a.b.*
  2. 导入
  3. X可能与编译单元
  4. 位于同一个包中。
  5. X可能是一种语言类型,即驻留在java.lang

我看到的问题是特别(2)。由于X可能是包私有类型,因此甚至不要求X驻留在名为X.java的编译单元中。因此,编译器必须查看类路径的所有条目,并搜索包foo.bar中的任何类,然后必须读取包foo.bar中的每个类,以检查是否包含X

听起来很贵。特别是当我只编译一个文件时,编译器必须读取几十个类文件才能找到一个类型X。如果我使用了大量的星型导入,那么这个过程就必须对许多类型重复执行(当然,类文件不会被读取两次)。

那么从同一个包中导入also类型以加快编译过程是否可取呢?或者是否有更快的方法来解决我无法找到的未导入类型X ?

听起来很贵。

如果编译器这样做,它将是昂贵的。

但实际发生的是,它构建了一个内存中的数据结构,其中包含类路径,bootclasspath和sourcepath上的所有类名,并将其用于javac运行中编译的所有类中的所有类名解析。

那么从同一个包中导入also类型以加快编译过程是否可取呢?或者是否有更快的方法来解决我无法找到的未导入类型X ?

No, and No。这几乎没有什么区别。此外,如果您按照设计的方式使用编译器,那么这不大可能成为一个重大的瓶颈。

最好以一种提供最易读和最可靠的代码的方式进行导入。

因此,编译器必须查看类路径的所有条目,并在包foo.bar

中搜索任何类。

这就是Class.forName()

则必须读取包foo中的所有类。栏检查是否包含X。

我不知道这是什么意思

通过Class.forName(),查找.class文件后,它必须在当前包的源路径中查找文件的适当名称,即new File(...).exists()等。

我不相信它会在每个文件中查找该名称的非公共类:您必须尝试它。如果是这样,这确实是一个昂贵的步骤,但我不相信它已经采取了

最新更新