Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java编译器如何解析未导入的名称_Java_Import_Token Name Resolution_Package Private - Fatal编程技术网

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

java编译器如何解析未导入的名称,java,import,token-name-resolution,package-private,Java,Import,Token Name Resolution,Package Private,假设我在包foo.bar中的java编译单元中使用类型X,并且X未在编译单元本身中定义,也未直接导入。java编译器现在如何高效地解析X?X可能存在以下几种可能性: X可以通过星型导入a.b.* X可能与编译单元位于同一个包中 X可能是一种语言类型,即驻留在java.lang 我看到的问题尤其严重。由于X可能是包私有类型,因此甚至不要求X驻留在名为X.java的编译单元中。因此,编译器必须查看类路径的所有条目并搜索包foo.bar中的任何类,然后必须读取包foo.bar中的每个类,以检查是否包含

假设我在包
foo.bar
中的java编译单元中使用类型
X
,并且
X
未在编译单元本身中定义,也未直接导入。java编译器现在如何高效地解析
X
X
可能存在以下几种可能性:

  • X
    可以通过星型导入
    a.b.*
  • X
    可能与编译单元位于同一个包中
  • X
    可能是一种语言类型,即驻留在
    java.lang
  • 我看到的问题尤其严重。由于
    X
    可能是包私有类型,因此甚至不要求
    X
    驻留在名为
    X.java
    的编译单元中。因此,编译器必须查看类路径的所有条目并搜索包
    foo.bar
    中的任何类,然后必须读取包
    foo.bar
    中的每个类,以检查是否包含
    X

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

    因此,建议也从同一个包中导入类型以加快编译过程吗?或者有没有更快的方法来解析我找不到的未变形类型
    X

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

    这只是
    Class.forName()

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

    我不知道这是什么意思

    在通过
    class.forName()查找.class文件之后,
    它必须在当前包的源路径中查找具有适当名称的文件,该文件就是
    新文件(…).exists()

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

    听起来很贵

    如果编译器那样做的话,代价会很高

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

    因此,建议也从同一个包中导入类型以加快编译过程吗?或者有没有一种更快的方法来解决我找不到的未损坏的X型问题

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


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

    您的计算机速度很快。找到类的引用不会花费很长时间。另外,可能会缓存Java库以缩短编译时间。不确定。当你说“当我只编译一个文件”时,你的意思是当我更改一个
    .java
    文件然后再编译时?我不敢相信这是一个在当今时代你需要担心的问题。如果这是一个纯粹的理论问题,我就不用担心了。如果你发现自己的表现很糟糕,那么再多告诉我们一点,也许我们可以做些什么来帮助你。@Duncan:嗯,大型项目的java构建恰好需要相当长的时间。如果为同一个包中的所有类添加导入可以减少编译时间20%,那么添加这些导入是值得的。因此,这个问题不是纯粹的理论问题。@gexicide也许你应该尝试一些实验?我仍然认为这不会有任何区别,而且您在大型项目上看到的大量编译时间是不相关的。您忽略了sourcepath的操作。证据将在编译器源代码中。但是您可以从
    forName
    实际加载类字节码并链接它们这一事实推断出这一点。字节码编译器不需要这样做,这样做会浪费CPU和内存。我的理解是,编译器有自己的类文件读取器,它只读取编译器需要的符号表信息。