实践篇-Java命令参数解析

简介: 大家我们写的源代码机器是识别不了的,机器只认识机器指令,所以我们的代码要想运行,这中间需要一些转换,因此我们就不得不提到命令这一概念了,用户输入`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


目录
相关文章
|
12月前
|
机器学习/深度学习 JSON Java
Java调用Python的5种实用方案:从简单到进阶的全场景解析
在机器学习与大数据融合背景下,Java与Python协同开发成为企业常见需求。本文通过真实案例解析5种主流调用方案,涵盖脚本调用到微服务架构,助力开发者根据业务场景选择最优方案,提升开发效率与系统性能。
2309 0
Java的CAS机制深度解析
CAS(Compare-And-Swap)是并发编程中的原子操作,用于实现多线程环境下的无锁数据同步。它通过比较内存值与预期值,决定是否更新值,从而避免锁的使用。CAS广泛应用于Java的原子类和并发包中,如AtomicInteger和ConcurrentHashMap,提升了并发性能。尽管CAS具有高性能、无死锁等优点,但也存在ABA问题、循环开销大及仅支持单变量原子操作等缺点。合理使用CAS,结合实际场景选择同步机制,能有效提升程序性能。
|
12月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
667 100
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
11月前
|
存储 安全 Java
《数据之美》:Java集合框架全景解析
Java集合框架是数据管理的核心工具,涵盖List、Set、Map等体系,提供丰富接口与实现类,支持高效的数据操作与算法处理。
|
12月前
|
Java 开发者
Java 函数式编程全解析:静态方法引用、实例方法引用、特定类型方法引用与构造器引用实战教程
本文介绍Java 8函数式编程中的四种方法引用:静态、实例、特定类型及构造器引用,通过简洁示例演示其用法,帮助开发者提升代码可读性与简洁性。
|
12月前
|
安全 Java API
Java SE 与 Java EE 区别解析及应用场景对比
在Java编程世界中,Java SE(Java Standard Edition)和Java EE(Java Enterprise Edition)是两个重要的平台版本,它们各自有着独特的定位和应用场景。理解它们之间的差异,对于开发者选择合适的技术栈进行项目开发至关重要。
1650 1
|
11月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
存储 缓存 算法
Java数据类型与运算符深度解析
本文深入解析Java中容易混淆的基础知识,包括八大基本数据类型(如int、Integer)、自动装箱与拆箱机制,以及运算符(如&与&&)的使用区别。通过代码示例剖析内存布局、取值范围及常见陷阱,帮助开发者写出更高效、健壮的代码,并附有面试高频问题解析,夯实基础。
|
算法 Java 测试技术
零基础学 Java: 从语法入门到企业级项目实战的详细学习路线解析
本文为零基础学习者提供完整的Java学习路线,涵盖语法基础、面向对象编程、数据结构与算法、多线程、JVM原理、Spring框架、Spring Boot及项目实战,助你从入门到进阶,系统掌握Java编程技能,提升实战开发能力。
827 0

推荐镜像

更多
  • DNS