【问题标题】:Why does `javac -cp` not need `.`, while `java -cp` does?为什么`javac -cp`不需要`.`,而`java -cp`需要?
【发布时间】:2019-04-11 12:44:53
【问题描述】:

我有两个问题:

为什么javac -cp 不需要.

$ javac -cp /home/t/programs/java/test/junit-4.11.jar TestCase.java

为什么java -cp 需要.

$ java -cp /home/t/programs/java/test/junit-4.11.jar:/home/t/programs/java/test/hamcrest-core-1.3.jar org.junit.runner.JUnitCore TestCase
JUnit version 4.11
Could not find class: TestCase

Time: 0.002

OK (0 tests)

$ java -cp .:/home/t/programs/java/test/junit-4.11.jar:/home/t/programs/java/test/hamcrest-core-1.3.jar org.junit.runner.JUnitCore TestCase
JUnit version 4.11
.running TestCase test1
.running TestCase test2

Time: 0.023

OK (2 tests)

TestCase.java:

import static org.junit.Assert.*;
import org.junit.Test;

// define a test case class, whose instances represent test cases
public class TestCase {

  @Test
  public void test1() {
      System.out.println("running TestCase test1");
      assertTrue(true);
  }

  @Test
  public void test2() {
      System.out.println("running TestCase test2");
      assertTrue(true);      
  }

}

【问题讨论】:

  • 这是一个真正的答案的百分之零,但是:Java 1 是一项紧急工作,他们弄错了一些东西。如果这种不一致只是他们没有注意到的事情,或者不是高优先级的修复,我不会感到惊讶。然后一旦它出来,他们就不想改变它。
  • @yshavit 不,完全一致,只是原因没有得到很好的解释。或者根本没有。

标签: java javac


【解决方案1】:

因为javac 处理文件,java 处理完全限定的类名。

编辑

稍微扩展一下,当你编译时,你将要编译的文件直接传递给javac,因此类路径仅用于包含编译你传递的文件所需的包作为论据。也就是说,您正在编译的文件不需要在类路径中。

另一方面,当您使用java 执行时,您是在告诉JVM“从类路径运行这个类”。当然,默认的类路径是.。但是后来您决定使用-cp 指定一个自定义类路径,它不会添加到类路径中,但会覆盖它。所以你必须明确地添加回来。

请参阅the last section of the official tutorial 进行确认。

【讨论】:

  • 处理包和类是不正确的,更正确的说法是处理完全限定的类名
【解决方案2】:

. 成为编译器类路径的一部分是隐式发生的几件事的结果。为了能够编译,在其他类中引用的生成类需要通过类路径访问。因此编译器将类文件目标路径添加到类路径中。如果您没有特别提供任何内容,那么该目录就是源目录。如果您没有具体提供,则使用进程的工作目录,默认为.

调用 javac -help 会显示不同的可能设置:

"c:\Program Files\Java\jdk1.8.0_181\bin\javac.exe" -help
Usage: javac <options> <source files>
where possible options include:
  -g                         Generate all debugging info
  -g:none                    Generate no debugging info
  -g:{lines,vars,source}     Generate only some debugging info
  -nowarn                    Generate no warnings
  -verbose                   Output messages about what the compiler is doing
  -deprecation               Output source locations where deprecated APIs are used
  -classpath <path>          Specify where to find user class files and annotation processors
  -cp <path>                 Specify where to find user class files and annotation processors
  -sourcepath <path>         Specify where to find input source files
  -bootclasspath <path>      Override location of bootstrap class files
  -extdirs <dirs>            Override location of installed extensions
  -endorseddirs <dirs>       Override location of endorsed standards path
  -proc:{none,only}          Control whether annotation processing and/or compilation is done.
  -processor <class1>[,<class2>,<class3>...] Names of the annotation processors to run; bypasses default discovery process
  -processorpath <path>      Specify where to find annotation processors
  -parameters                Generate metadata for reflection on method parameters
  -d <directory>             Specify where to place generated class files
  -s <directory>             Specify where to place generated source files
  -h <directory>             Specify where to place generated native header files
  -implicit:{none,class}     Specify whether or not to generate class files for implicitly referenced files
  -encoding <encoding>       Specify character encoding used by source files
  -source <release>          Provide source compatibility with specified release
  -target <release>          Generate class files for specific VM version
  -profile <profile>         Check that API used is available in the specified profile
  -version                   Version information
  -help                      Print a synopsis of standard options
  -Akey[=value]              Options to pass to annotation processors
  -X                         Print a synopsis of nonstandard options
  -J<flag>                   Pass <flag> directly to the runtime system
  -Werror                    Terminate compilation if warnings occur
  @<filename>                Read options and filenames from file

我提到的选项是-s-sourcepath-cp 用于定义编译器可以查找已编译类的附加位置(目录和库文件)。这也是-cp在调用java时的含义,所以这两个可执行文件没有矛盾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 2018-07-30
    • 2011-06-18
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多