写在前面
源码 。
本文来用纯纯的Java代码来实现java -version
的效果,就像下面这样:
1:程序
这里输出类似这样的:
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
版本号信息比较简单,使用我们最拿手的sout就可以了,但是要获取用户设置的参数我们以我们现有的能力是做不到的,必须借助于外部力量了,也就是jar包:
<dependencies><!-- 命令行参数解析器 --><dependency><groupId>com.beust</groupId><artifactId>jcommander</artifactId><version>1.72</version></dependency>
</dependencies>
通过该类库我们可以很容易的获取到用户指定的命令行参数,接着解析命令行参数就可以给出用户想要的信息了:
public class Cmd {@Parameter(names = {"-?", "-help"}, description = "print help message", order = 3, help = true)boolean helpFlag = false;@Parameter(names = "-version", description = "print version and exit", order = 2)boolean versionFlag = false;@Parameter(names = {"-cp", "-classpath"}, description = "classpath", order = 1)String classpath;@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;}static Cmd parse(String[] argv) {Cmd args = new Cmd();JCommander cmd = JCommander.newBuilder().addObject(args).build();cmd.parse(argv);args.ok = true;return args;}}
核心是注解com.beust.jcommander.Parameter
,如果运行指定了某个参数则对应的布尔值就会被设置为true(如设置了-version 则versionFlag就会在解析后设置为true)
。参数的解析工作通过方法static Cmd parse(String[] argv)
完成,接着编写如下的测试类:
package com.dahuyou.write.jvm.version;public class Main {public static void main(String[] args) {Cmd cmd = Cmd.parse(args);if (!cmd.ok || cmd.helpFlag) {System.out.println("Usage: <main class> [-options] class [args...]");return;}if (cmd.versionFlag) {System.out.println("java version \"9(mine)\"\n" +"Java(TM) SE Runtime Environment (build 9+181)\n" +"Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)");return;}startJVM(cmd);System.out.println("xxxxxxxxxxxxx");}private static void startJVM(Cmd cmd) {System.out.printf("classpath:%s class:%s args:%s\n", cmd.classpath, cmd.getMainClass(), cmd.getAppArgs());}}
编译:
接着运行(命令行方式):
E:\workspace-idea2019\waste-time-javaagent-and-javassist\target\classes>java -classpath D:\mvn_rep\mvn_rep_361\com\beust\jcommander\1.72\jcommander-1.72.jar;E:\workspace
-idea2019\write-jvm-self-query-java-version\target\classes com.dahuyou.write.jvm.version.Main -version
java version "9(mine)"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
这里要注意在-classpath中除了要指定依赖的jar外,还需要指定依赖的自己的class字节码文件
(这个点卡了我好久/(ㄒoㄒ)/~~)
。另外,这里的-classpath也可以简写为-cp
。
运行(idea方式):
写在后面
参考文章列表
java编译和运行带有包名的类 。