实践篇-Java命令参数解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 大家我们写的源代码机器是识别不了的,机器只认识机器指令,所以我们的代码要想运行,这中间需要一些转换,因此我们就不得不提到命令这一概念了,用户输入`java`命令,然后对命令进行解析,解析之后给出相应的结果,听起来是不是很酷,很有意思对不对?那就让我带大家来玩一下吧。

Java命令与用法

`Java`命令一般有以下2种形式:

//java [-options] class [args]//java [-options] -jar jarfile [args]


我们的 `java` 命令需要携带三组参数:分别是选项主类名(或者JAR文件名)。选项是由`-`开头的,比如我们熟悉的 `-version`(输出产品版本并退出),当然被括起来证明是可选的,如果选用非选项参数,那你就得给出全的主类名,如果你选择`-jar`选项那接着就得跟`jar`文件名,然后就可以从这个文件中寻找主类了。


这里提到了主类,什么是主类呢?我们知道所有的java程序运行,都有一个main方法,这个方法也被称为我们程序的入口点,public static void main(String[] args) ,那该方法所在的类我们就叫主类


那什么是选项呢?选项就是java给我们提供的一个功能项,使用的时候用 [-options]表示,那java都给我们提供了哪些功能项呢?有很多。


选项

用途

 -server

选择 "server" VM

 默认 VM 是 server.

 -cp 

<目录和 zip/jar 文件的类搜索路径>

-classpath 

<目录和 zip/jar 文件的类搜索路径>

                 用 ; 分隔的目录, JAR 档案

                 和 ZIP 档案列表, 用于搜索类文件。

-verbose

[class|gc|jni]

启用详细输出

 -? -help 

 输出此帮助消息

-Xms<size> 设置初始堆空间大小
-Xmx<size> 设置最大堆空间大小
-Xss<size> 设置线程栈空间大小

java命令与实现

那作为一个菜鸡,我肯定是不可能全实现的,所以我挑了一些比较容易的进行实现:

1.  `java -version` 输出产品版本并退出

1.  `java -help -?` 输出此帮助消息

1.  `java -cp your/classpath yourClassName arg1 ...`<目录和 zip/jar 文件的类搜索路径>

1.  `java -classpath your/classpath yourClassName arg1 arg2 ...`<目录和 zip/jar 文件的类搜索路径>用 ; 分隔的目录, JAR 档案 和 ZIP 档案列表, 用于搜索类文件。


实现思路

1. 把java命令看成一串字符,那我们就可以用String类型的字符进行接收

2. 然后把命令切割成字符数组,用于命令参数解析,给不同的解析结果给不同的标识

3. 将解析结果的标识取出,根据标识进行相应结果的返回

4. 结束并退出程序


代码实现

首先定义一个命令类,用于命令校验和标识,之后提供一些属性值,代码如下:

privateBooleanversionFlag=false; //版本命令标记privateBooleanhelpFlag=false;      //帮助命令标记privateBooleanisRightFormat=true; //校验命令格式是否正确privateBooleanisRightOpt=true; //校验命令格式是否正确privateStringclazz;   //要编译的java文件privateString[] args; //执行Java文件所需的参数privateStringcpOption;  //classPath 的路径; java -cp(-classpath) xxx/*使用 -Xjre 的选项:这是一个非标准的选项,java命令中是没有的,使用这个选项目的是用来指定启动类路径来寻找和加载Java标准库中的类即JAVA_HOME/jre的路径;这里要注意的是,如果真的要指定XjreOption,那么其路径值必须要用双引号包含起来*/privateStringxjreOption;//-Xjre 的路径;

然后写一个解析命令的方法,代码如下:

publicCmd(String[] args) {
parseCmd(args);
}

接下来我们把方法实现一下,在实现之前我们可以思考一下,都要校验什么,命令参数的长度关键字语法,大概也就这些,好,我们开始干。代码如下:

首先校验基本格式:

intclassNameIndex=1;
if (args.length<2) {
//最简短的java命令:java -version,参数长度更小的,肯定不合法isRightFormat=false;
return ;
}

接着判断java命令:

//接着判断开头是不是 java ,如果不是,证明不是可运行的java命令;if (!"java".equals(args[0])) {
isRightFormat=false;
} else {
if ("-help".equals(args[1]) ||"-?".equals(args[1])) {
helpFlag=true;
    } elseif ("-version".equals(args[1])) {
versionFlag=true;
    } elseif ("-cp".equals(args[1]) ||"classpath".equals(args[1])) {
//到这一步的命令不是cp就是classpath,所以长度至少有4个if (args.length<4) {
isRightFormat=false;
        }
classNameIndex=3;
//由于该命令需要知道类路径,故添加字段this.cpOption=args[2];
    } elseif ("-Xjre".equals(args[1])) {
//如果走到这一步,那么命令行必定是java -Xjre "C:\Program Files\Java\jdk1.8.0_20\jre" java.lang.Object 的形式if (args.length<4) {
isRightFormat=false;
        }
classNameIndex=3;
this.xjreOption=args[2];
    } elseif ("-".startsWith(args[1])) {
isRightOpt=false;
    }
this.clazz=args[classNameIndex];
this.args=newString[args.length-classNameIndex+1];
intargsIndex=classNameIndex+1;
for (inti=argsIndex; i<args.length; i++) {
this.args[i-argsIndex] =args[i];
    }
}
//命令行格式错误,输出错误信息publicvoidprintUsage() {
System.out.println("Unrecognized option: --\n"+"Error: Could not create the Java Virtual Machine.\n"+"Error: A fatal exception has occurred. Program will exit.\n");
}

到这,一个命令类就定义完了,然后我们回到主程序。代码如下:

publicclassStartApplication {
publicstaticvoidmain(String[] args) {
//        String s = "java -version";while (true) {
System.out.println("please input java cmd:");
Scannersc=newScanner(System.in);
StringinputCmd=sc.nextLine();
System.out.println("input java cmd:"+inputCmd);
Cmdcmd=newCmd(inputCmd.split(" "));
if (!cmd.getIsRightFormat()) {
cmd.printUsage();
            } else {
if (cmd.getVersionFlag()) {
System.out.println("java version "1.8.0_202"\n"+"Java(TM) SE Runtime Environment (build 1.8.0_202-b08)\n"+"Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)\n");
                } elseif (cmd.getHelpFlag() ) {
System.out.println("这是帮助命令");
                } else {
System.out.println("欢迎来到JVM");
                }
            }
        }
    }
}

然后我们来看效果,图如下:

1630713905(1).jpg


目录
相关文章
|
3天前
|
存储 缓存 安全
Java内存模型深度解析:从理论到实践####
【10月更文挑战第21天】 本文深入探讨了Java内存模型(JMM)的核心概念与底层机制,通过剖析其设计原理、内存可见性问题及其解决方案,结合具体代码示例,帮助读者构建对JMM的全面理解。不同于传统的摘要概述,我们将直接以故事化手法引入,让读者在轻松的情境中领略JMM的精髓。 ####
20 6
|
11天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
39 2
|
15天前
|
Java
轻松上手Java字节码编辑:IDEA插件VisualClassBytes全方位解析
本插件VisualClassBytes可修改class字节码,包括class信息、字段信息、内部类,常量池和方法等。
66 6
|
2天前
|
数据采集 存储 Web App开发
Java爬虫:深入解析商品详情的利器
在数字化时代,信息处理能力成为企业竞争的关键。本文探讨如何利用Java编写高效、准确的商品详情爬虫,涵盖爬虫技术概述、Java爬虫优势、开发步骤、法律法规遵守及数据处理分析等内容,助力电商领域市场趋势把握与决策支持。
|
6天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
7天前
|
Java 测试技术 API
Java 反射机制:深入解析与应用实践
《Java反射机制:深入解析与应用实践》全面解析Java反射API,探讨其内部运作原理、应用场景及最佳实践,帮助开发者掌握利用反射增强程序灵活性与可扩展性的技巧。
|
12天前
|
存储 算法 Java
Java Set深度解析:为何它能成为“无重复”的代名词?
Java的集合框架中,Set接口以其“无重复”特性著称。本文解析了Set的实现原理,包括HashSet和TreeSet的不同数据结构和算法,以及如何通过示例代码实现最佳实践。选择合适的Set实现类和正确实现自定义对象的hashCode()和equals()方法是关键。
23 4
|
15天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
12天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
15天前
|
Java 编译器 数据库连接
Java中的异常处理机制深度解析####
本文深入探讨了Java编程语言中异常处理机制的核心原理、类型及其最佳实践,旨在帮助开发者更好地理解和应用这一关键特性。通过实例分析,揭示了try-catch-finally结构的重要性,以及如何利用自定义异常提升代码的健壮性和可读性。文章还讨论了异常处理在大型项目中的最佳实践,为提高软件质量提供指导。 ####

推荐镜像

更多
下一篇
无影云桌面