用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编译和运行带有包名的类 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/843291.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

突破•指针二

听说这是目录哦 复习review❤️野指针&#x1fae7;assert断言&#x1fae7;assert的神奇之处 指针的使用和传址调用&#x1fae7;数组名的理解&#x1fae7;理解整个数组和数组首元素地址的区别 使用指针访问数组&#x1fae7;一维数组传参的本质&#x1fae7;二级指针&#x…

filebeat,kafka,clickhouse,ClickVisual搭建轻量级日志平台

springboot集成链路追踪 springboot版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.3</version><relativePath/> <!-- lookup parent from…

python—爬虫爬取电影页面实例

下面是一个简单的爬虫实例&#xff0c;使用Python的requests库来发送HTTP请求&#xff0c;并使用lxml库来解析HTML页面内容。这个爬虫的目标是抓取一个电影网站&#xff0c;并提取每部电影的主义部分。 首先&#xff0c;确保你已经安装了requests和lxml库。如果没有安装&#x…

HTML零基础自学笔记(上)-7.18

HTML零基础自学笔记&#xff08;上&#xff09; 参考&#xff1a;pink老师一、HTML, Javascript, CSS的关系是什么?二、什么是HTML?1、网页&#xff0c;网站的概念2、THML的基本概念3、THML的骨架标签/基本结构标签 三、HTML标签1、THML标签介绍2、常用标签图像标签&#xff…

数据结构----算法复杂度

1.数据结构前言 数据是杂乱无章的&#xff0c;我们要借助结构将数据管理起来 1.1 数据结构 数据结构(Data Structure)是计算机存储、组织数据的⽅式&#xff0c;指相互之间存在⼀种或多种特定关系的数 据元素的集合。没有⼀种单⼀的数据结构对所有⽤途都有⽤&#xff0c;所…

ranger审计日志对接CDH solr

作者&#xff1a;耀灵 一、准备条件 1、已安装完毕ranger-admin 2、已在CDH上部署solr&#xff08;注意在安装solr时更改下solr在zk上的节点信息&#xff09; 二、更改相关配置 1、修改ranger-2.1.0-admin/contrib/solr_for_audit_setup/install.properties SOLR_USERsolr …

科研绘图系列:R语言单细胞聚类气泡图(single cell bubble)

介绍 单细胞的标记基因气泡图是一种用于展示单细胞数据中特定基因表达情况的可视化方法。它通常用于展示细胞亚群中标记基因的表达水平,帮助研究者识别和区分不同的细胞类型。在这种图表中,每个细胞亚群用不同的颜色表示,而基因表达水平则通过气泡的大小来表示,从而直观地…

嵌入式C++、FreeRTOS、MySQL、Spring Boot和MQTT协议:智能零售系统详细流程介绍(代码示例)

项目概述 随着科技的发展&#xff0c;零售行业正经历着一场数字化转型。智能零售系统通过集成嵌入式技术和大数据分析&#xff0c;为商家提供了高效的运营管理工具。该系统的核心目标是提升顾客体验、优化库存管理、降低运营成本以及实现精准营销。 本项目将结合多种技术栈&a…

tree组件实现折叠与展开功能(方式1 - expandedTree计算属性)

本示例节选自vue3最新开源组件实战教程大纲&#xff08;持续更新中&#xff09;的tree组件开发部分。考察响应式对象列表封装和computed计算属性的使用&#xff0c;以及数组reduce方法实现结构化树拍平处理的核心逻辑。 实现思路 第一种方式&#xff1a;每次折叠或展开后触发…

【LeetCode】对称二叉树

目录 一、题目二、解法完整代码 一、题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#…

洗地机哪个牌子好性价比高又实惠?四款洗地机好洗地机的品牌推荐

在追求家居清洁效率与成本效益并重的今天&#xff0c;选择一款性价比高且实惠的洗地机显得尤为重要。市场上洗地机品牌琳琅满目&#xff0c;至于洗地机哪个牌子好性价比高又实惠成为很多人心中的疑问。为此&#xff0c;我们精心搜集并推荐四款洗地机好洗地机的品牌&#xff0c;…

数据结构之跳表SkipList、ConcurrentSkipListMap

概述 SkipList&#xff0c;跳表&#xff0c;跳跃表&#xff0c;在LevelDB和Lucene中都广为使用。跳表被广泛地运用到各种缓存实现当中&#xff0c;跳跃表使用概率均衡技术而不是使用强制性均衡&#xff0c;因此对于插入和删除结点比传统上的平衡树算法更为简洁高效。 Skip lis…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(七)-广播远程识别码(Broadcast Remote ID)

目录 引言 5.5 广播远程识别码&#xff08;Broadcast Remote ID&#xff09; 5.5.1 使用PC5的广播远程识别码 5.5.2 使用MBS的广播远程识别码 引言 3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及…

达梦数据库DM8-索引篇

目录 一、前景二、名词三、语法1、命令方式创建索引1.1 创建索引空间1.2.1 创建普通索引并指定索引数据空间1.2.2 另一种没验证&#xff0c;官方写法1.3 复合索引1.4 唯一索引1.5 位图索引1.6 函数索引 2、创建表时候创建索引3、可视化方式创建索引3.1 打开DM管理工具3.2 找到要…

appium2.0 执行脚本遇到的问题

遇到的问题&#xff1a; appium 上的日志信息&#xff1a; 配置信息 方法一 之前用1.0的时候 地址默认加的 /wd/hub 在appium2.0上&#xff0c; 服务器默认路径是 / 如果要用/wd/hub 需要通过启动服务时设置基本路径 appium --base-path/wd/hub 这样就能正常执行了 方法二…

利用request + BeautifulSoup 模块批量爬取内容,实现批量获取书名对应的豆瓣评分

文章目录 代码代码解释控制台输出结果 代码 #-*- coding:utf-8 -*- from bs4 import BeautifulSoup import requests, time, jsonheaders {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.39…

初识godot游戏引擎并安装

简介 Godot是一款自由开源、由社区驱动的2D和3D游戏引擎。游戏开发虽复杂&#xff0c;却蕴含一定的通用规律&#xff0c;正是为了简化这些通用化的工作&#xff0c;游戏引擎应运而生。Godot引擎作为一款功能丰富的跨平台游戏引擎&#xff0c;通过统一的界面支持创建2D和3D游戏。…

jmeter-beanshell学习11-从文件获取指定数据

参数文件里的参数可能过段时间就不能用了&#xff0c;需要用新的参数。如果有多个交易&#xff0c;读不同的参数文件&#xff0c;但是数据还是一套&#xff0c;就要改多个参数文件。或者只想执行参数文件的某一行数据&#xff0c;又不想调整参数文件顺序。 第一个问题目前想到…

Transformer 翻译

Attention Is All You Need Ashish Vaswani∗ Google Brain avaswanigoogle.com Noam Shazeer∗ Google Brain noamgoogle.com Niki Parmar∗ Google Research nikipgoogle.com Jakob Uszkoreit∗ Google Research uszgoogle.com Llion Jones∗ Google Research lliongoogle.c…

mysql字符类型字段设置默认值为当前时间

-- 2024-07-22 10:22:20 select (DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)); ALTER TABLE tablename MODIFY COLUNN CREATE_DATE varchar (23) DEFAULT(DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)) COMMENT "创建日期;