具有循环导入的Java文件

时间:2014-07-28 15:57:52

标签: java import javac

我想了解javac如何处理循环导入。经过几次尝试,我得到了以下代码进行编译:

package com.test.p1;    
import com.test.p2.ClassP2;    
public class ClassP1 {

    public static void main(String[] args) {
        System.out.println("ClassP1 loaded");           
        ClassP2.testP2();       
    }
}

package com.test.p2;    
import com.test.p1.ClassP1;    
public class ClassP2 {

    public static void testP2() {
        System.out.println("ClassP2 loaded");
    }
}

当我首先编译ClassP2.java时,由于ClassP1.java尚未编译且未生成class文件,因此我预计它会失败。然而,它编译好了,并生成了ClassP2.classClassP1.class。运行ClassP1也很好。

现在我的问题是当我只编译ClassP2时javac如何为ClassP1生成类文件。为什么当循环引用不存在时不会发生这种情况 - 即ClassP2导入ClassP1但ClassP1不导入ClassP2?

我还是Java的新手,并试图了解编译的工作原理。

2 个答案:

答案 0 :(得分:1)

这里没有任何循环。听起来你和很多其他人一样,混淆了导入和类加载。

所有import语句都允许您使用短名称来引用代码中的Java类:

import java.sql.ResultSet;

public V find() {
    ResultSet rs = null;  // You can type ResultSet instead of java.sql.ResultSet
}

如果短名称不明确(例如同一类中的java.util.Datejava.sql.Date),则导入语句无法帮助您。

在您的代码在运行时需要它之前,java.sql.ResultSet的字节代码不会加载到JVM中。

答案 1 :(得分:0)

它不是循环导入的结果,它是在ClassP2.java中导入ClassP1而javac能够根据您传递给javac的参数找到ClassP1的源的结果。执行命令的位置。

请参阅javac的文档中的-sourcepath选项:

  

-sourcepath sourcepath   指定源代码路径以搜索类或接口定义。与用户类路径一样,源路径条目由分号(;)分隔,可以是目录,JAR存档或ZIP存档。如果使用了包,则目录或存档中的本地路径名必须反映包名。   注意:如果找到了源,则可以通过类路径找到的类进行自动重新编译。请参阅搜索类型。