参数文件可以是javac命令中的部分内容,比如可以是java文件的路径列表文件,将参数保存为文本中供编译时引用,缩短执行命令长度,避免命令行参数过长报错。
可匹配源码目录下的java文件列表作为参数文件
find src -name "*.java" > sourcefiles.txtsourcefiles.txt
Main.java PrintService.java接着就可以通过 @+sourcefiles.txt 对列表文件进行引用,放到javac命令行中
#生成字节码与源码同目录 javac @sourcefiles.txt #指定存在的目录输出字节码 javac -d target @sourcefiles.txt当然不仅是源码列表,还可以加上参数,如图
10. 编译脚本示例 10.1. Linux编译脚本 compile.sh源码文件处在 src 目录中,创建输出目录 target, 依赖包目录 lib
在工程目录下创建如下编译脚本:
compile.sh
#!/bin/bash # 编译脚本 # @author: Hellxz #出现变量取值失败、报错立即停止 set -eu #定义变量 SOURCE=src TARGET=target LIBRARY=libs #清理历史编译结果 [ -d "${TARGET}" ] && rm -rf ${TARGET}/* #输出参数文件 echo "-d ${TARGET} -encoding utf-8" > argsfile find ${SOURCE} -name "*.java" >> argsfile #编译源文件 if [ -d "${LIBRARY}" ]; then javac -cp "${LIBRARY}/*" @argsfile else javac @argsfile fi #删除参数文件 rm -rf argsfile echo "compile success!" 10.2. Windows编译脚本 compile.bat @echo off REM 源码目录 set srcdir=src REM 目标目录 set targetdir=target REM jar包外部依赖目录 set libsdir=libs REM 清理缓存 if exist %targetdir% ( echo clean target caches... del /f /s /q %targetdir%\*.* rd /s /q %targetdir% md %targetdir% echo clean caches success! ) else ( md %targetdir% ) REM 生成参数文件 echo generating argsfile.txt echo -d %targetdir% -encoding utf-8 > argsfile.txt where -r %srcdir% *.java >> argsfile.txt echo generate argsfile success! REM 编译 echo compiling... if exist %libsdir% ( javac -cp "%libsdir%\*" @argsfile.txt ) else ( javac @argsfile.txt ) REM 删除参数文件 del /f /q /a argsfile.txt echo compile success! pause 三、执行字节码 1. java 执行字节码命令java 命令用于执行 javac编译出的字节码文件,启动 Java 虚拟机。
java 命令语法为:
java [options] classname [args]options:选项参数,包含Java虚拟机参数等设定
classname:字节码文件,.class 后缀的文件
args:参数,将作为 main 方法的参数传入程序中
options参考:
2. 执行字节码文件一般而言,执行 Java 程序直接用 java 命令就可以
#执行带main方法的字节码 java mainclass 3. 执行带package的字节码当源码中有package提示包名时,执行的class需要放在层层包名目录中,举例:
package samples; public class Main { public static void main(String[] args) { System.out.println("Hello World"); } }编译后Main.class 的位置在 /opt/target/samples/Main.class
执行java命令就需要进到 /opt/target 下,与第一层包目录平级
cd /opt/target java samples/Main.class不进入包名目录上级,可以设置 classpath 来指定待执行查找class的起点
java -cp /opt/target samples/Main 3. 执行有外部依赖关系的字节码src/samples/Main.java
package samples; import com.alibaba.fastjson.JSONObject; public class Main { public static void main(String[] args) { JSONObject json = new JSONObject(); json.put("hello", "world"); System.out.println(json.toJSONString()); } }外部依赖libs目录、源码目录src、生成class目录target,src下有一个包为samples的Main.java,如下图
编译src目录源码,生成字节码到target下
javac -cp "src:libs/*" -d target $(find src -name "*.java")设置classpath,执行字节码文件
java -cp "target:libs/*" samples.Main 参考资料:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html
https://zhuanlan.zhihu.com/p/74229762