JCommanderの@Parameterのメモ。
|
JCommanderでは、コマンドラインパラメーターを解析
した結果の値を入れるクラスを、ユーザープログラマーが用意する。
そのクラスでは、フィールドに@Parameterアノテーションを付けて、コマンドラインパラメーターを定義する。
※全フィールドに影響する設定は、@Parametersアノテーションで行う。
import com.beust.jcommander.Parameter;
public class MyArgument { @Parameter(names = { "-n", "--name" }, description = "user name") private String name = "hishidama"; @Parameter(names = { "-f", "--file" }, description = "file") private Path file; public String getName() { return this.name; } public Path getFile() { return this.file; } }
@Parameterアノテーションを付けるフィールドの可視性は何でもいい。
(リフレクションで値が読み書きされるので、privateフィールドでもいい(実行環境のセキュリティー設定で「privateにアクセス可能」にする必要はあるが、通常はアクセス可能))
フィールドのデータ型はString以外でも良い。
値はその型に変換される。数値やbooleanの他、列挙型やURI・Path等に対応している。
独自のConverterを作ることも出来る模様。
フィールドに初期値を持たせると、デフォルト値になる。
(usage()でもデフォルト値として表示される)
なお、データ型にプリミティブ型(intやboolean等)を使うと、usage()で常にデフォルト値が表示されてしまう。
ラッパークラス(IntegerやBoolean等)を使えば(初期値をnullにしておけば)デフォルト値は表示されない。
設定名 | デフォルト値 | 例 | 説明 | |
---|---|---|---|---|
names |
String[] |
{} |
names = "-f" names = { "-f", "--file" } |
パラメーター名。 →名前の無いパラメーター |
description |
String |
空文字列 |
description = "file" |
パラメーターの説明。 usage()で表示される。 |
descriptionKey |
String |
空文字列 | @ParametersのresourceBandleから説明文を取得する為のキーらしい。 | |
required |
boolean |
false |
required = true |
必須パラメーターかどうか。 trueにすると、必須になる。 必須の場合、フィールドの初期値(デフォルト値)を定義していても、パラメーターが指定されていなかったらエラーになる。 |
arity |
int |
-1 |
arity = 1 |
パラメーターの後に指定する値の個数。 デフォルトは、booleanだと0個で、それ以外は1個。 2個以上にするときは、フィールドのデータ型をListにする。 →arityの例 |
variableArity |
boolean |
false |
variableArity = true |
trueにすると、パラメーターの後に複数個(個数不定)の値を指定できる。→例 |
password |
boolean |
false |
||
echoInput |
boolean |
false |
||
converter |
Class |
|||
listConverter |
Class |
|||
validateWith |
Class |
|||
validateValueWith |
Class |
|||
splitter |
Class |
パラメーターの後続の値を区切って複数の値にするクラス。 デフォルトでは、カンマで区切る。 |
||
forceNonOverwritable |
boolean |
false |
||
help |
boolean |
false |
help = true |
ヘルプコマンドかどうか。→ヘルプの例 |
order |
int |
-1 |
usage()で表示するときの順序。[2022-09-14] 連番である必要はない。 指定が無いときはパラメーターのアルファベット順になるっぽい。 |
|
hidden |
boolean |
false |
usage()に表示する(隠す)かどうか。 trueにすると、そのパラメーターはusage()で表示されなくなる。 |
データを受け取るクラスの中のひとつのフィールドだけ、名前の無いパラメーター(@Parameterのnamesを書かないフィールド)を定義することが出来る。
そこには、名前無しで列挙されたパラメーター(main parameter)が入ってくる。
public class MyArgument {
〜
@Parameter(description = "<main1> <main2>...") // no names
private List<String> mainParameterList;
public Optional<String> findMainParameter(int index) {
if (mainParameterList != null && index < mainParameterList.size()) {
return Optional.of(mainParameterList.get(index));
}
return Optional.empty();
}
}
java -cp 〜 JCommanderExample --name hishidama a b c
→mainParameterListにa, b, cが入る。
フィールドのデータ型をbooleanにすることは出来るが、usage()で表示したときに「Default:
false」と表示されてしまう。
データ型をBoolean(ラッパークラス)にしておけば、デフォルト値は表示されなくなる。
public class MyArgument { 〜 @Parameter(names = { "--on" }, description = "switch on") private Boolean on; public boolean isOn() { return (this.on != null) && this.on; } }
※ヘルプはboolean型でもusage()でデフォルト値は表示されない
また、真偽値は、デフォルトではパラメーターの後続に値を書かないが、arityを1にすればtrue/falseを渡せるようになる。
コーディング例 | 引数の例 | 結果 |
---|---|---|
@Parameter(names = "b") private boolean b; |
-b |
b=true |
|
b=false |
|
@Parameter(names = "b0", arity = 0) private boolean b0; |
-b0 |
b0=true |
|
b0=false |
|
@Parameter(names = "b1", arity = 1) private boolean b1; |
-b1 true |
b1=true |
-b1 false |
b1=false |
arityで、パラメーターの後に続く値の個数を指定する。[2022-09-13]
値の個数が不定な場合は、variableArityを指定する。
複数個の値を受け取るときはデータ型をListにする。
独自クラスで受け取ることも出来る。(独自クラスのフィールドに@SubParameterアノテーションを付ける)
コーディング例 | 引数の例 | 結果 | 備考 | |
---|---|---|---|---|
引数1個 |
@Parameter(names = "-s1", arity=1) private List<String> s1; |
-s1 a b c |
s1=[a] |
|
引数2個 |
@Parameter(names = "-s2", arity=2) private List<String> s2; |
-s2 a b c
|
s2=[a, b] |
|
引数可変個 |
@Parameter(names = "-sv", variableArity=true) private List<String> sv;
|
-sv a b c |
sv=[a, b, c] |
|
-sv a b -s1 c |
sv=[a, b] |
|||
引数を受け取るクラス |
import com.beust.jcommander.SubParameter; public class MyPair { @SubParameter(order = 0) public String key; @SubParameter(order = 1) public String value; } @Parameter(names = "-p", arity=2) private MyPair p; |
-p a b c |
p.key=a |
フィールドがpublicでないとエラーになる。 (ver 1.82) |
引数の直後に値 |
import com.beust.jcommander.DynamicParameter; @DynamicParameter(names = "-D") Map<String, String> d = new HashMap<>(); |
-Da=1 -D b=2 |
d={a=1, b=2} |
データ型はMap。 インスタンスも与える必要がある。 値は「K=V」の形式のみ有効。 |
よくあるアプリケーションでは、「-?
」や「--help
」でヘルプ(使用方法)が表示される。
JCommanderを使う場合でも、これらは自分で実装する必要がある。
class MyArgument { @Parameter(names = { "-?","--help" }, description = "print usage", help = true) private boolean help; public boolean isHelp() { return this.help; } }
var argument = new MyArgument(); var commander = JCommander.newBuilder().addObject(argument).build(); commander.parse(args); if (argument.isHelp()) { commander.usage(); // 使用方法(パラメーターの種類)を表示 System.exit(0); }
@Parameterのhelpをtrueにしておくと、多少他と異なる挙動をする。