有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

具有循环导入的Java文件

我试图理解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文件。然而,它编译了ok,并生成了ClassP2.classClassP1.class。运行ClassP1也很好

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

我对Java还是一个新手,并试图了解编译是如何工作的


共 (2) 个答案

  1. # 1 楼答案

    这不是循环导入的结果,而是在类P2中导入类P1的结果。java和javac能够根据传递给javac的参数和执行命令的位置找到ClassP1的源代码

    有关javac,请参见文档中的-sourcepath选项:

    -sourcepath sourcepath Specify the source code path to search for class or interface definitions. As with the user class path, source path entries are separated by semicolons (;) and can be directories, JAR archives, or ZIP archives. If packages are used, the local path name within the directory or archive must reflect the package name. Note: Classes found through the class path may be subject to automatic recompilation if their sources are also found. See Searching For Types.

  2. # 2 楼答案

    这里什么都没发生。听起来像是你和其他很多人混淆了导入和类加载

    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在同一个类中),import语句对您没有帮助

    直到代码在运行时需要时,java.sql.ResultSet的字节码才会加载到JVM中