java类路径之谜:要么是我的类,要么是jar,但不是两者都有?

java类路径之谜:要么是我的类,要么是jar,但不是两者都有?,java,classpath,jna,Java,Classpath,Jna,考虑以下java程序: import computer_package.Computer; import com.sun.jna.Library; public class HelloWorld { public static void main(String[] args) { Computer computer = new Computer(); System.out.println("Hello, World"); } } 以及以下目录结构

考虑以下java程序:

import computer_package.Computer;
import com.sun.jna.Library;
public class HelloWorld {
    public static void main(String[] args) {
        Computer computer = new Computer();
        System.out.println("Hello, World");
    }
}
以及以下目录结构:

Rebs-MacBook-Pro:jalint2 rebcabin$ find computer_package/
computer_package/
computer_package//Computer.class
computer_package//Computer.java
其中
Computer.java
如下:

package computer_package;
public class Computer {
    public Computer() {
        System.out.println("Constructor of Computer class.");
    }
    public void computer_method() {
        System.out.println("Power gone! Shut down your PC soon...");
    }
}
另一个目录中只有
jar
文件:

Rebs-MacBook-Pro:jalint2 rebcabin$ find com
com
com/sun
com/sun/jna
com/sun/jna/jna-4.0.0.jar
com/sun/jna/jna-platform-4.0.0.jar
如果我只注释掉
import com.sun.jnaHelloWorld.java
文件中的代码>行,然后所有的工作都很好

Rebs-MacBook-Pro:jalint2 rebcabin$ javac -g HelloWorld.java 
Rebs-MacBook-Pro:jalint2 rebcabin$ java HelloWorld
Constructor of Computer class.
Hello, World
Javac和java能够找到类文件
/computer\u package/computer.class
,而无需任何进一步的提示、注释或类路径黑客攻击

现在,如果我恢复
import com.sun.jna行并注释掉
导入计算机\u package.computer行和该行构成一台新计算机,并按如下方式编译:

Rebs-MacBook-Pro:jalint2 rebcabin$ javac -g -cp "./com/sun/jna/jna-4.0.0.jar" HelloWorld.java
Rebs-MacBook-Pro:jalint2 rebcabin$ make
javac -g -cp "./com/sun/jna/jna-4.0.0.jar:./computer_package" HelloWorld.java
甚至像这样:

Rebs-MacBook-Pro:jalint2 rebcabin$ javac -g -cp "./com/sun/jna/jna-4.0.0.jar" HelloWorld.java
Rebs-MacBook-Pro:jalint2 rebcabin$ make
javac -g -cp "./com/sun/jna/jna-4.0.0.jar:./computer_package" HelloWorld.java
那么一切都还不错:

Rebs-MacBook-Pro:jalint2 rebcabin$ java HelloWorld
Hello, World
至少,
导入com.sun.jna行没有抛出编译器错误——诚然,我还没有使用jna库;我只是试着以婴儿的步子来建立这一重大成就

因此,如果我现在谨慎地取消对
import computer\u包的注释行和构造
计算机
实例的行,生成问题顶部的
HelloWorld.java
文件,该文件试图同时使用我的
计算机
类和jna,所有的麻烦都没有了;以前可接受的
计算机
类现在无法访问:

Rebs-MacBook-Pro:jalint2 rebcabin$ make
javac -g -cp "./com/sun/jna/jna-4.0.0.jar:./computer_package" HelloWorld.java
HelloWorld.java:20: error: package computer_package does not exist
import computer_package.Computer;
                       ^
HelloWorld.java:25: error: cannot access Computer
        Computer computer = new Computer();
        ^
  bad class file: ./computer_package/Computer.class
    class file contains wrong class: computer_package.Computer
    Please remove or make sure it appears in the correct subdirectory of the classpath.
2 errors
make: *** [HelloWorld.class] Error 1

我知道这是基本的;我不是一名java专家,我承认我正在尝试猜测自己在类路径噩梦世界中的道路;我只使用emacs和bash,避免使用添加更多不透明抽象层的IDE

您需要将classpath指定为包含包的目录,而不是包的类,因此如果您是从同一目录运行的:

javac -g -cp "./com/sun/jna/jna-4.0.0.jar:./"

请注意,如果不指定类路径,默认情况下将使用当前目录。参见

我消除了jna文件的干扰,发布了一个更简单的案例;看起来这里的@SimonC的答案也适用于这种情况。@HovercraftFullOfEels,别担心!我删除了另一个更简单的案例,因为这一个是第一个得到回答的(当这个答案出现时,我的另一个问题的帖子正在进行中:)