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. 结束并退出程序
代码实现
首先定义一个命令类,用于命令校验和标识,之后提供一些属性值,代码如下:
private Boolean versionFlag = false; //版本命令标记 private Boolean helpFlag = false; //帮助命令标记 private Boolean isRightFormat = true; //校验命令格式是否正确 private Boolean isRightOpt = true; //校验命令格式是否正确 private String clazz; //要编译的java文件 private String[] args; //执行Java文件所需的参数 private String cpOption; //classPath 的路径; java -cp(-classpath) xxx /*使用 -Xjre 的选项:这是一个非标准的选项,java命令中是没有的,使用这个选项目的是用来指定启动类路径来寻找和加载Java标准库中的类 即JAVA_HOME/jre的路径; 这里要注意的是,如果真的要指定XjreOption,那么其路径值必须要用双引号包含起来 */ private String xjreOption;//-Xjre 的路径;
然后写一个解析命令的方法,代码如下:
public Cmd(String[] args) { parseCmd(args); }
接下来我们把方法实现一下,在实现之前我们可以思考一下,都要校验什么,命令参数的长度,关键字,语法,大概也就这些,好,我们开始干。代码如下:
首先校验基本格式:
int classNameIndex = 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; } else if ("-version".equals(args[1])) { versionFlag = true; } else if ("-cp".equals(args[1]) || "classpath".equals(args[1])) { //到这一步的命令不是cp就是classpath,所以长度至少有4个 if (args.length < 4) { isRightFormat = false; } classNameIndex = 3; //由于该命令需要知道类路径,故添加字段 this.cpOption = args[2]; } else if ("-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]; } else if ("-".startsWith(args[1])) { isRightOpt = false; } this.clazz = args[classNameIndex]; this.args = new String[args.length - classNameIndex + 1]; int argsIndex = classNameIndex + 1; for (int i = argsIndex; i < args.length; i++) { this.args[i - argsIndex] = args[i]; } }
//命令行格式错误,输出错误信息 public void printUsage() { 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"); }
到这,一个命令类就定义完了,然后我们回到主程序。代码如下:
public class StartApplication { public static void main(String[] args) { // String s = "java -version"; while (true) { System.out.println("please input java cmd:"); Scanner sc = new Scanner(System.in); String inputCmd = sc.nextLine(); System.out.println("input java cmd:"+inputCmd); Cmd cmd = new Cmd(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"); } else if (cmd.getHelpFlag() ) { System.out.println("这是帮助命令"); } else { System.out.println("欢迎来到JVM"); } } } } }
然后我们来看效果,图如下:
- 本文作者: CoCaCoder
- 其它文章链接: https://juejin.cn/post/7003892309041348639
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!