Java怎么解析命令行参数

Python061

Java怎么解析命令行参数,第1张

用惯了控制台的java程序之后,最印象深刻的是其的简单与快捷,虽没有图形界面那样吸引人的眼球,但却也足以迷倒众生。那么java命令行参数有哪些呢?跟gkstk小编一起来学习吧!

控制台程序的运行少不了要通过控制台来传递参数,譬如:

Sh代码

ls -la

这是shell脚本的常用命令,其就是通过后置参数来传递相关信息。UNIX环境为C语言中提供了getopt()这样的函数可以解析后置参数,这个函数是很实用很强大的,但Java就...(我Google了一下,倒没有怎么找出来)。大概是这个功能对Java来说太不足挂齿了吧,但总得有个解决方法才行。

下面就是一个代码实例,用以说明。

这个实例运行的结果是运行在控制台,并允许可选的输入参数:

Sh代码

java TestOpt -i 89 -b -s TestString

那么就会设置几个prarameter的值

Java代码

public class TestOpt {

public static void main(String[] args) {

/*

* 这里先取默认值,因为不是所有参数都会被用户提供

*/

boolean prarameter1 = false

int prarameter2 = 0

String prarameter3 = ""

/*

* 设置一个offset变量,用来定位相关信息

*/

int optSetting = 0

for (optSetting <args.lengthoptSetting++) {

if ("-b".equals(args[optSetting])) {

prarameter1 = true

} else if ("-i".equals(args[optSetting])) {

prarameter2 = Integer.parseInt(args[++optSetting])

} else if ("-s".equals(args[optSetting])) {

prarameter3 = args[++optSetting]

}

}

/*

* 这里我只是打印出来相关的设置信息,具体的行为肯定是要自己取定义打

*/

System.out.println(prarameter1)

System.out.println(prarameter2)

System.out.println(prarameter3)

}

}

这种类似的方法估计应该有很多吧,但这个应该算是比较轻量级的。当然若参数非常多(同时也得进行验证输入)

在hotspot/src/share/vm/runtime/globals.hpp以及各组件、平台相关的*_gloabals.hpp有这些VM参数的声明,然后在对应的cpp文件里有它们的实现。

在product build中,被宏展开之后实际上会变成:

在JavaMain()函数中会创建虚机:

创建虚拟机的函数中,首先会进行虚拟机参数解析并设置好相应的全局变量的值,例如UseParallelGC。然后在init_globals()中就会根据UseParallelGC在创建堆设置好GC回收策略。

parse_each_vm_init_arg会遍历获取到的参数列表,然后根据各参数进行相应的设置和赋值。-XX:+UseParallelGC最后会调用process_argument(tail, args->ignoreUnrecognized, origin)进行设置。

Flag的数据结构(runtime/globas.hpp):

flagTable这个Flag数组记录了VM参数的名字与存储位置(地址)之间的对应关系。于是通过它就可以实现从字符串到实际全局变量的赋值。

遍历flagTable找到名字所指定的Flag:

然后通过Flag里记录的地址给VM参数对应的全局变量赋值:

在Universe::create_heap()中会根据前面解析出来的堆相关参数,进而创建所需要的堆,并设置相应的GC回收策略。

查找"JavaMain"在哪个文件中:

grep -rn "JavaMain" jdk/src/

查找"Threads::create_vm"方法在哪个文件中:

grep -rn "Threads::create_vm" hotspot/

查找Arguments::parse

查找"Universe::initialize_heap"