这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
背景
Java虚拟机非常复杂,要想真正理解它的工作原理,最好的方式就是自己动手写一个。
本实现参考《自己动手写java 虚拟机》、《Java虚拟机规范》 、《小傅哥的相关博客》等。
jcommander介绍
//pom文件
<!-- 命令行参数解析器 -->
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.72</version>
</dependency>
更多相关命令行解析的只是请参考
JCommander 是一个非常小的 Java 框架,它使得解析命令行参数变得微不足道。您可以使用选项描述来注释字段:
class Main {
@Parameter(names={"--length", "-l"})
int length;
@Parameter(names={"--pattern", "-p"})
int pattern;
public static void main(String ... argv) {
Main main = new Main();
JCommander.newBuilder()
.addObject(main)
.build()
.parse(argv);
main.run();
}
public void run() {
System.out.printf("%d %d", length, pattern);
System.out.println();
}
}
在启动参数配置
结果
512 2
代码
命令行工具
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import java.util.List;
/**
* @Author blackcat
* @create 2021/8/11 13:42
* @version: 1.0
* @description:命令行相关参数
*/
public class Cmd {
@Parameter(names = {"-?", "-help"}, description = "print help message", help = true)
boolean helpFlag = false;
@Parameter(names = "-version", description = "print version and exit")
boolean versionFlag = false;
@Parameter(names = {"-cp", "-classpath"}, description = "classpath")
String classpath;
@Parameter(names = "-Xjre", description = "path to jre")
String jre;
@Parameter(description = "main class and args")
List<String> mainClassAndArgs;
boolean ok;
String getMainClass() {
return mainClassAndArgs != null && !mainClassAndArgs.isEmpty()
? mainClassAndArgs.get(0)
: null;
}
List<String> getAppArgs() {
return mainClassAndArgs != null && mainClassAndArgs.size() > 1
? mainClassAndArgs.subList(1, mainClassAndArgs.size())
: null;
}
public static Cmd parse(String[] argv) {
Cmd cmd = new Cmd();
try {
JCommander.newBuilder().addObject(cmd).args(argv).build();
cmd.ok = true;
} catch (Exception e) {
e.printStackTrace();
}
return cmd;
}
}
测试代码
/**
* @Author blackcat
* @create 2021/8/11 14:08
* @version: 1.0
* @description:
*/
public class Main {
public static void main(String[] args) {
String[] argv = {"-Xjre" ,"D:\\tools\\Jdk1.8\\jre","-classpath","MainTest","MainTest","agr1","agr2"};
Cmd cmd = Cmd.parse(argv);
if (!cmd.ok || cmd.helpFlag) {
System.out.println("Usage: <main class> [-options] class [args...]");
return;
}
if (cmd.versionFlag) {
System.out.println("java version \"1.8.0\"");
return;
}
startJVM(cmd);
}
private static void startJVM(Cmd cmd) {
System.out.printf("classpath:%s class:%s args:%s\n", cmd.classpath, cmd.getMainClass(), cmd.getAppArgs());
}
}
//classpath:MainTest class:MainTest args:[agr1, agr2]