📜  如何运行不同目录中的Java类文件

📅  最后修改于: 2020-02-10 15:31:46             🧑  作者: Mango

在本文中,我们将学习如何使用其他项目的实用程序、类和成员。在继续之前,让我们了解一些关键字。

类路径

类路径是JVM开始执行程序的位置。与经典的动态加载行为类似,Java虚拟机在执行Java程序时会懒惰地查找和加载类(仅在首次使用该类时才加载类的字节码)。类路径告诉Java在文件系统中哪里查找定义这些类的文件。在类路径中可访问和可用的变量和方法称为类路径变量。默认情况下,JVM在执行程序时始终访问类路径类。JVM总是进入类路径的深处以搜索类或资源。
JVM按照以下顺序搜索和加载类:

  1. bootstrap类: Java平台的基础类(包括Java类库的公共类和该库正常运行所必需的私有类)。
  2. 扩展类:位于JRE或JDK扩展目录中的软件包,jre/lib/ext/用户定义的软件包和库

使用导入关键字

import关键字在Java中用于从当前项目的类路径中导入类。您可以从不同的包但从相同的类路径导入类。要记住,类的包装是从类路径开始的。假设您具有以下目录结构:

a > b > c > d > class A

并且您的类路径从c开始,那么您的类应该在d包中,而不在abcd中

使用classpath -cp选项

import关键字可以从当前类路径中导入类,不能在类路径之外使用。现在,假设您已经有一个项目,在其中使用了一些实用程序类,这在第二个项目中也需要。然后在这种情况下,import关键字不起作用,因为您的第一个项目在另一个类路径中。在这种情况下,可以在编译和执行程序时使用-cp命令。
让我们继续下面的示例。创建一个目录结构,如下图所示:


 
在这里,您有2个项目proj1和proj2。proj1包含src和类。在src目录中,我们将保留作为源文件的.java文件,而在classes目录中,将保留作为编译项目后生成的文件的.classes文件。
以下是运行位于不同目录中的Java类文件的步骤:

    • 步骤1(创建程序类):在src目录中创建包含以下代码的A.java。
      // Java类A
      public class A
      {
          public void test()
          {
              System.out.println("Test() method of class A");
          }
      }

      在这里,我们有一个实用程序类A。

    • 步骤2(编译实用程序类):在proj1位置打开终端并执行以下命令。
      cp_tutorial/proj2>cd src
      cp_tutorial/proj2/src>Javac -d ../classes -cp
      ../../proj1/classes MainClass.Java
    • -d选项:用于将输出存储到其他目录。如果我们不使用此选项,则将在src目录中创建类文件。但是,最好将源文件和类文件分开保存。在-d选项之后,我们提供了应在其中存储类文件的目录位置。
      如果有任何编译时错误,请先解决它,然后再继续。
    • 步骤3(检查A.java是否已成功编译):在proj1的classes目录中检查是否创建了类文件。如果您的程序已成功编译,肯定会创建。
    • 步骤4(编写主类并进行编译):移至proj2目录。出于相同的原因,这里也是2个目录。在src目录中创建具有以下内容的MainClass.java并尝试对其进行编译。
      //Java类,执行程序
      public class MainClass{
          public static void main(String[] args){
              System.out.println("In main class");
              A a1 = new A();
              a1.test();
          }
      }
      cp_tutorial/proj2>cd src
      cp_tutorial/proj2/src>Javac -d ../classes MainClass.Java
      MainClass.Java:4: error: cannot find symbol
                      A a1 = new A();
                      ^
        symbol:   class A
        location: class MainClass
      MainClass.Java:4: error: cannot find symbol
                      A a1 = new A();
                                 ^
        symbol:   class A
        location: class MainClass
      2 errors
    • 如您所见,存在编译时错误,未找到符号A。如果要使用proj1的类A,则必须使用-cp选项包括proj1的资源,如下一步所示。
    • 步骤5(使用-cp选项编译):
cp_tutorial/proj2>cd src
cp_tutorial/proj2/src>Javac -d ../classes -cp
../../proj1/classes MainClass.Java
      • 现在,您的代码将成功编译,并在classes目录中创建MainClass.class。-cp代表classpath,它包括当前classpath给出的路径,一旦包含,JVM就会识别符号A,它是一个类,并成功编译了文件。
      • 步骤6(执行程序):尝试执行程序。执行以下命令以运行您的程序。
        cp_tutorial/proj2/src>cd ../classes
        cp_tutorial/proj2/classes>Java MainClass
        Exception in thread "main" java.lang.NoClassDefFoundError: A
                at MainClass.main(MainClass.Java:4)
        Caused by: java.lang.ClassNotFoundException: A
                at Java.net.URLClassLoader$1.run(Unknown Source)
                at Java.net.URLClassLoader$1.run(Unknown Source)
                at Java.security.AccessController.doPrivileged(Native Method)
                at Java.net.URLClassLoader.findClass(Unknown Source)
                at java.lang.ClassLoader.loadClass(Unknown Source)
                at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
                at java.lang.ClassLoader.loadClass(Unknown Source)
                ... 1 more
      • 糟糕,我们收到未找到A类的错误。这是因为您仅在编译时告诉JVM有关A的路径。在运行MainClass时,他不知道其他项目中有A类。
      • 步骤7(使用-cp选项执行):我们必须再次提供类A的路径。
        cp_tutorial/proj2/classes>Java -cp ../../proj1/classes; MainClass
        In main class
        Test() method of class A

        现在,您已经成功运行了程序。别忘了在提供类路径之后加上’;’ 。对于OS / Linux,替换“;” 为’:’。

如何在类路径中运行带有jar的Java类?

您也可以使用jar文件来代替来自不同类路径的类文件。过程将相同,您只需要用jar文件夹替换classes文件夹,并用jar名称替换类名即可。
假设您在lib目录中有jar文件,那么可以使用进行编译

cp_tutorial/proj2/src>Javac -d ../classes -cp ../../proj1/lib MainClass.Java

并执行:

cp_tutorial/proj2/classes>Java -cp ../../proj1/lib; MainClass