在实际的项目中用到命令行的并不是很常见,但当真正使用到时,特别是在程序启动时配置一下参数的时候就很有用了,如果参数很多的话,一个一个解析命令行还是比较麻烦的.这时使用Args4J就相当好办了. 在本文中我们来看看Args4J的使用,当需要时能提供一个解决方案.
Args4J使用一个被称为Option类的类来保存输入的参数,让后根据该类来应用参数,每个参数可以对应一个类中的属性,该属性用Annotation注释,在Annotation中给出该参数 的选项, 还可以配置其他有用的信息.该Annotation就是 Option 注解: 该注解的doc如下:
Marks a field/setter that receives a command line switch value.
This annotation can be placed on a field of type T or the method of the form void methodName(T value). Its access modified can be anything, but if it's not public, your application needs to run in a security context that allows args4j to access the field/method (seeAccessibleObject.setAccessible(boolean)
.
The behavior of the annotation differs depending on T --- the type of the field or the parameter of the method.
When T is boolean , it represents a boolean option that takes the form of "-OPT". When this option is set, the property will be set to true.
When T is String
, it represents an option that takes one operand. The value of the operand is set to the property.
When T is derived from Enum
, it represents an option that takes an operand, which must be one of the enum constant. The comparion between the operand and the enum constant name is done in a case insensitive fashion.
For example, the following definition will represent command line options like "-coin penny" or "-coin DIME" but things like "-coin" or "-coin abc" are errors.
enum Coin { PENNY,NICKEL,DIME,QUARTER } class Option { @Option(name="-coin") public Coin coin; }
When T is a File
, it represents an option that takes a file/directory name as an operand.
该注解有5各域 其中name是必须的,其他四个是可选的.如下所示,关于该注解的详细Doc请查看 其docs.
Required Element Summary | |
---|---|
String | name Name of the option, such as "-foo" or "-bar". |
Optional Element Summary | |
---|---|
Class<? extendsOptionHandler> | handler Specify the OptionHandler that processes the command line arguments. |
String | metaVar When the option takes an operand, the usage screen will show something like this: |
boolean | required Specify that the option is mandatory. |
String | usage Help string used to display the usage screen. |
当命令行设定后 其使用方式和java 命令里面的参数使用方式一样 如:java -cp ./calssPath/.......
下面通过一个例子来解释:
001 /*
002 * Created on 2006-2-21
003 * @author icerain
004 */
005 package test.args4j;
006
007 import org.kohsuke.args4j.Argument;
008 import org.kohsuke.args4j.CmdLineException;
009 import org.kohsuke.args4j.CmdLineParser;
010 import org.kohsuke.args4j.ExampleMode;
011 import org.kohsuke.args4j.Option;
012 import org.kohsuke.args4j.spi.BooleanOptionHandler;
013
014 import java.io.File;
015 import java.io.IOException;
016 import java.util.ArrayList;
017 import java.util.List;
018
019 public class TestArgs4J {
020 // 利用Option注解来定义一个boolean 命令行参数 其参数name为 -re ,required指定该参数是必须的
021 @Option(name = "-re", usage = "recursively run something", required = true)
022 private boolean recursive;
023
024 //利用Option注解定义一个File 命令行参数, name为-o, 输入时候知道该file的路径就可以了
025 //metaVar 用来设定显示 使用方式时候的输出,这个输出为-o OUTPUT : output to this file
026 //如果不指定该属性 则使用默认的代替 为-o FILE : output to this file
027 @Option(name = "-o", usage = "output to this file", metaVar = "OUTPUT")
028 private File out = new File(".");
029
030 //If 'usage' value is empty, the option will not be displayed
031 // in the usage screen.
032 //注意该处没有指定 usage 属性 或者指定usage 但是其值为空的 如usage = "",这样当使用
033 //parser.printExample(ExampleMode.ALL) 请注意下面第92行的输出
034 @Option(name = "-str", required = true)
035 //@Option(name = "-str", usage = "测试", required = true) // 该行 -str参数有用
036 // no usage
037
038 private String str = "(default value)";
039
040 // 整数参数
041 @Option(name = "-n", usage = "repeat <n> times\nusage can have new lines in it and also it can be verrry long")
042 private int num = -1;
043
044 // using 'handler=...' allows you to specify a custom OptionHandler
045 // implementation class. This allows you to bind a standard Java type
046 // with a non-standard option syntax
047 //指定一个特定的handler
048 @Option(name = "-custom", handler=BooleanOptionHandler.class,usage="boolean value for checking the custom handler")
049 private boolean data;
050
051 // receives other command line parameters than options
052 @Argument
053 private List<String> arguments = new ArrayList<String>();
054
055 public static void main(String[] args) throws IOException {
056 new TestArgs4J().doMain(args);
057 }
058
059 public void doMain(String[] args) throws IOException {
060 //Creates a new command line owner that parses arguments/options
and set them into the given object.
061 CmdLineParser parser = new CmdLineParser(this);
062
063 try {
064 // parse the arguments.
065 parser.parseArgument(args);
066
067 // you can parse additional arguments if you want.
068 // parser.parseArgument("more","args");
069
070 // after parsing arguments, you should check
071 // if enough arguments are given.
072 if (arguments.isEmpty())
073 throw new CmdLineException("No argument is given");
074
075 } catch (CmdLineException e) {
076 // if there's a problem in the command line,
077 // you'll get this exception. this will report
078 // an error message.
079 System.err.println(e.getMessage()); //打印出错消息
080 System.err.println("java SampleMain [options...] arguments...");
081 // print the list of available options
082 parser.printUsage(System.err); // 打印参数的用法
083 System.err.println();
084
085 System.err.println("测试!!!!!");
086 // print option sample. This is useful some time
087 System.err.println(" Example: java SampleMain"
088 + parser.printExample(ExampleMode.ALL));
// 注意 在Option中如果没有指定 usage 属性,
089 System.err.println("/n 2.........");
//则这两行程序不会输出该参数的使用的
090
091 System.err.println(" 2 Example2: java SampleMain"
//注意 在Option中如果没有指定 usage 属性,
092 + parser.printExample(ExampleMode.REQUIRED));
//则这两行程序不会输出该参数的使用的
093 return;
094 }
095
096 // this will redirect the output to the specified output
097 System.out.println(out);
098
099 if (recursive)
100 System.out.println("-r flag is set");
101
102 if (data)
103 System.out.println("-custom flag is set");
104
105 System.out.println("-str was " + str);
106
107 if (num >= 0)
108 System.out.println("-n was " + num);
109
110 // access non-option arguments
111 System.out.println("other arguments are:");
112 for (String s : arguments)
113 System.out.println(s);
114 }
115
116 }
当不使用命令行时候 输入信息如下:
Option "-re" is required
java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
usage can have new lines in it and also it can be verrrrrrr
rrrrrrrrrrry long
-o OUTPUT : output to this file
-re : recursively run something
测试!!!!!
Example: java SampleMain -custom -n N -o OUTPUT -re
// 注意该处没有 -str的出现/n 2.........
2 Example2: java SampleMain -re
// 注意该处没有 -str的出现当使用 -re 为命令行输入时,输出如下:// 后为作者加的注释 不是输出
Option "-str" is required
//也要指定-str该参数java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
usage can have new lines in it and also it can be verrrrrrr
rrrrrrrrrrry long
-o OUTPUT : output to this file
-re : recursively run something
测试!!!!!
Example: java SampleMain -custom -n N -o OUTPUT -re
/n 2.........
2 Example2: java SampleMain -re
当使用-re -str some 为命令行输入时,结果如下:这是由于的73 行的判断引起的
No argument is given
java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
usage can have new lines in it and also it can be verrrrrrr
rrrrrrrrrrry long
-o OUTPUT : output to this file
-re : recursively run something
测试!!!!!
Example: java SampleMain -custom -n N -o OUTPUT -re
/n 2.........
2 Example2: java SampleMain -re
使用-custom -n 2 -re -str some otherstring 为命令行输入时的 结果如下:
. // file
-r flag is set
-custom flag is set
-str was some
-n was 2
other arguments are:
otherstring
当使用-custom -n 2 -re -str some -o log.txt otherstring 时候的输出如下:
log.txt
-r flag is set
-custom flag is set
-str was some
-n was 2
other arguments are:
otherstring
当使用一个不存在的参数时候 会有Exception的 例如:-custom -ee 2 -re -str some -o log.txt otherstring
其中-ee参数不存在 结果如下:
"-ee" is not a valid option
java SampleMain [options...] arguments...
-custom : boolean value for checking the custom handler
-n N : repeat <n> times
......
由以上的实例可以看出 args4J 取得命令行的输入参数,然后根据保存参数的类中的属性类型比较
并转换为适当的值, 然后我们可以使用这些属性了,这样就免去了自己判断args 的麻烦了,
当默认的Handler不满足你的要求时 可以自己扩展Handler实现,关于这点请参考Args4J的测试用例,