为什么`javac -cp`不需要`.`,而`java -cp`却需要呢?

时间:2019-04-11 12:44:54

标签: java javac

我有两个问题:

为什么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);      
  }

}

2 个答案:

答案 0 :(得分:7)

由于javac处理文件,java处理完全合格的类名。

编辑

为了扩展一点,在编译时,您将要编译的文件直接传递到javac,因此类路径仅用于包含编译文件时所需要的包。重新传递为参数。也就是说,您正在编译的文件不需要在类路径中。

另一方面,当您使用java执行时,您是在告诉JVM“从类路径运行此类”。当然,默认类路径为.。但是随后您决定使用-cp指定一个自定义类路径,该类路径不会添加到类路径中,而是会自动添加。因此,您必须将其明确添加回去。

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

答案 1 :(得分:1)

.属于编译器的类路径,是隐式发生的几件事的结果。为了能够进行编译,需要通过classpath访问在其他类中引用的生成的类。因此,编译器将class-file-destination路径添加到classpath。如果您没有提供任何特别说明,则该目录为源目录。如果您未提供具体使用的进程的工作目录,则默认为.

呼叫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时的含义,因此这两个可执行文件之间没有矛盾。