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

📅  最后修改于: 2022-05-13 01:54:30.015000             🧑  作者: Mango

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

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

类路径

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

JVM 按以下顺序搜索和加载类:

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

使用导入关键字

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

a > b > c > d > class A

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

使用类路径 -cp 选项

import 关键字可以从当前类路径导入类,类路径之外的导入不能使用。现在假设您已经有一个项目,其中使用了一些实用程序类,您的第二个项目也需要这些类。然后在这种情况下 import 关键字不起作用,因为您的第一个项目位于另一个类路径中。在这种情况下,您可以在编译和执行程序时使用-cp命令。

让我们继续下面的例子。创建如下图所示的目录结构。

cp_tutorial

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

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

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

  • 第 2 步(编译实用程序类):在 proj1 位置打开终端并执行以下命令。
    cp_tutorial/proj1>cd src
    cp_tutorial/proj1/src>javac -d ../classes A.java
    

    -d 选项:用于将输出存储到不同的目录。如果我们不使用此选项,则将在 src 目录中创建类文件。但最好将源文件和类文件分开保存。在 -d 选项之后,我们提供了应该存储类文件的目录的位置。
    如果有任何编译时错误,请在继续之前解决它。

  • 第三步(查看Java是否编译成功):查看proj1的classes目录下是否创建了class文件。如果您的程序编译成功,那肯定是肯定的。
  • 第 4 步(编写主类并编译它):移动到您的 proj2 目录。出于同样的原因,这里还有 2 个目录。创建主类。 src 目录下的Java有以下内容,并尝试编译它。
    //java class to execute program
    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 代表类路径,它包含当前类路径给出的路径,一旦包含,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 文件代替来自不同类路径的类文件。该过程将是相同的,您只需将 classes 文件夹替换为 jar 文件夹,并将类名替换为 jar 名称。
假设你在 lib 目录中有 jar 文件,然后编译你可以使用

cp_tutorial/proj2/src>javac -d ../classes -cp ../../proj1/lib MainClass.java

并执行

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

相关文章:设置Java环境