您的位置:首页 > 财经 > 金融 > 用Java手写jvm之实现java -version的效果

用Java手写jvm之实现java -version的效果

2024/12/27 4:05:55 来源:https://blog.csdn.net/wang0907/article/details/140608010  浏览:    关键词:用Java手写jvm之实现java -version的效果

写在前面

源码 。
本文来用纯纯的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编译和运行带有包名的类 。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com