问题引入: 在工作当中因为部署好的代码有可能只有几行代码可以修改,这时候如果仍然在idea上面修改好后,打包再部署,那感觉太麻烦又费时间。因此

想在线上服务器上面直接通过javac编译的方式编译单个文件即可。

javac 语法
用法:javac <options> <source files> <@files>

source files: 一个或多个要编译的源文件(.java文件)

@files:一个或多个 包含待编译.java文件列表 的文件。

注:当要编译的.java文件较少,直接在javac命令后接上源文件列表即可,例如:javac SourceFile1.java SourceFile2.java 当要编译的Java文件较多时可以使用*.java通配,也可以将源文件名列在一个文件中(任意后缀均可,例如:sourcefiles.anything),然后在 javac 命令行中使用该列表文件名,文件名前冠以 @ 字符,即:javac @sourcefiles.anything

options:编译选项/参数
-g                                  生成所有调试信息
-g:none                          不生成任何调试信息
-g:{lines,vars,source}     只生成某些调试信息
-nowarn                          不生成任何警告
-verbose                         输出有关编译器正在执行的操作的消息
-deprecation                   输出使用已过时的 API 的源位置
-classpath <路径>          指定查找用户类文件和注释处理程序的位置
-cp <路径>                     指定查找用户类文件和注释处理程序的位置
-sourcepath <路径>       指定查找输入源文件的位置
-bootclasspath <路径>   覆盖引导类文件的位置
-extdirs <目录>              覆盖所安装扩展的位置
-endorseddirs <目录>    覆盖签名的标准路径的位置
-proc:{none,only}           控制是否执行注释处理和/或编译。
-processor <class1>[,<class2>,<class3>...] 要运行的注释处理程序的名称; 绕过默认的搜索进程
-processorpath <路径>        指定查找注释处理程序的位置
-parameters                         生成元数据以用于方法参数的反射
-d <目录>                    指定放置生成的类文件的位置
-s <目录>                    指定放置生成的源文件的位置
-h <目录>                    指定放置生成的本机标头文件的位置
-implicit:{none,class}     指定是否为隐式引用文件生成类文件
-encoding <编码>             指定源文件使用的字符编码
-source <发行版>              提供与指定发行版的源兼容性
-target <发行版>              生成特定 VM 版本的类文件
-profile <配置文件>            请确保使用的 API 在指定的配置文件中可用
-version                   版本信息
-help                      输出标准选项的提要
-A关键字[=值]                  传递给注释处理程序的选项
-X                                输出非标准选项的提要
-J<标记>                     直接将 <标记> 传递给运行时系统
-Werror                    出现警告时终止编译
@<文件名>             从文件读取选项和文件名

常用的几个命令如下:

  • -d
指定放置生成的类文件的位置,eg:javac -d <destdir> Xxx.java。缺省情况下class文件和源文件存放同一级目录,不会自动建包结构的文件夹存放生成的class文件。当指定了<destdir>时,如果编译的类带有包名的话会自动把包建好。<destdir>必须存在,不会自动创建不存在的指定路径,否则报错如下:javac: 找不到目录:<destdir>
  • -classpath/-cp
设置用户类路径,它将覆盖CLASSPATH 环境变量中的用户类路径,多个路径之间用分号(;)分隔。若缺省则默认当前路径。
  • -sourcepath
指定用以查找类或接口定义的源代码路径。与用户类路径一样,多个源路径项用分号 (;) 进行分隔,它们可以是目录、JAR 归档文件或 ZIP 归档文件。如果使用包,那么目录或归档文件中的本地路径名必须反映包名。通过类路径查找的类,如果找到了其源文件,则可能会自动被重新编译。

注意:在javac命令中-classpath和-sourcepath都是用于指定编译当前类文件 需要的调用其他路径上的类或源文件 的位置。

  • -classpath用来指定搜索类文件(.class文件)的路径,-sourcepath用来指定搜索源文件(.java文件)的路径
  • 如果未指定-sourcepath,将会在classpath指定的路径中查找类文件(.class文件)和源文件(.java文件)。如果指定了sourcepath则不会在classpath路径下查找源文件。
  • 如果找到了源文件(.java文件),可能会重新生成类文件(.class文件)
相对路径与绝对路径

在编译指定源文件的时候,可以在源文件下进行cmd操作,执行javac编译,也可以在其他盘目录下进行javac编译。只要能通过路径(相对路径/绝对路径)找到对应的源文件即可。

现准备一个源文件JavacTest.java, 绝对路径如下。

D:\code project\java\javac_test\src\com\tx\test\JavacTest.java
package com.tx.test;

public class JavacTest {
    public static void main(String[] args) {
        System.out.println("javac...");
    }
}
  • 使用相对路径,生成的.class文件和源文件在一个文件夹下。

javac 编译的文件怎么运行 javac编译文件夹_源文件

或者直接在源文件下的目录,执行命令,后面直接跟类名即可:

javac 编译的文件怎么运行 javac编译文件夹_javac 编译的文件怎么运行_02

  • 使用绝对路径,执行命令

javac 编译的文件怎么运行 javac编译文件夹_javac 编译的文件怎么运行_03

这中间有个小问题,当路径种有空格的时候,咋办,这时候可以将路径用" "双引号引起来即可。

当源文件中引入外部文件的时候

Person.java文件

package com.tx.bean;

public class Person {
    private int age;
    private String name;

	// 构造方法,get、set、tostring方法
}

这时候javacTest.java 中加入新的代码,引入Person.

package com.tx.test;

import com.tx.bean.Person;

public class JavacTest {
    public static void main(String[] args) {
        System.out.println("javac...");
        Person person = new Person(18, "张三");

        System.out.println(person);
    }
}

这个时候如果再用javac编译就会报错,提示找不到符号Person

javac 编译的文件怎么运行 javac编译文件夹_java_04

因为编译器会从当前目录下(D:\code project\java\javac_test\src\com\tx\test)找有没有Person.java,没有的话,就会到环境变量配置的classpath中去找,找不到后就报错了。

所以我们需要指定的Person在哪里。

javac 编译的文件怎么运行 javac编译文件夹_源文件_05

这里通过-sourcepath来指定Person源代码的位置。

注意: 通过import的外部类,如果有包名的话,那么编译器在找外部类的时候会根据你指定的源码位置sourcepath或者classpath 后面跟上包名。

参考: https://blog.51cto.com/u_14120/6372613