4

考虑我X在包中的 java 编译单元中使用了一个类型,foo.bar并且X没有在编译单元本身中定义,也没有直接导入。java编译器X现在如何有效地解析?有几种可能X存在的地方:

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

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

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

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

4

2 回答 2

1

这听起来非常昂贵。

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

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

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

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

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

于 2014-06-07T02:47:38.600 回答
0

因此,编译器必须查看类路径的所有条目并搜索包 foo.bar 中的任何类

那只是Class.forName()

然后它必须读取包 foo.bar 中的每个类以检查是否包含 X。

我不知道这是什么意思。

在通过Class.forName(),它查找 .class 文件之后,必须在当前包中的源路径中查找具有适当名称的文件这就是new File(...).exists()etc。

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

于 2014-06-06T22:29:16.000 回答