Java コマンドライン引数処理

photo of person typing on computer keyboard

Javaで以下のようにコマンドライン引数を渡して処理を分岐する方法を紹介します。

$ java MyApplication -count 500 -name Taro
目次

Javaコマンドライン引数

Javaのコマンドライン引数の渡し方

Javaプログラム起動時に指定したコマンドライン引数は、mainメソッドの引数の配列として渡されます。引数はスペース区切りで異なる引数値として解釈されます。

 public static void main(final String[] args) {
$ java MyApplication a b c

args[0] = a
args[1] = b
args[2] = c

文字列の適切な型変換

渡された引数はString型のため、プログラム中でStringから数値等に変換する必要があります。この他以外にもすべてのプリミティブ型への変換の仕組みが用意されています。

int i = Integer.parseInt("1000");
long l = Long.parseLong("1234567891203123");
float f = Float.parseFloat(123.456);
double d = Integer.parseDouble("1234.567");
boolean b = Parse.Boolean("true"); 

自前で処理する場合

public class MyApplication {
    private static int number = 10;
    private static String name = "DefaultName";

    public static void main(final String[] args) {
        for (int i=0; i<args.length; ++i) {
            if ("-count".equals(args[i])) {
                number = Integer.parseInt(args[++i]);
            } else if ("-name".equals(args[i])) {
                name = args[++i];
            } else {
	        System.err.println("未定義の引数が渡されました");
            }
        }
     }
}

コマンドライン引数の処理ライブラリを用いる

Javaでは様々なコマンドライン引数の処理ライブラリが提供されています。これらを用いることで安全に楽に定型的な引数処理を実現できるでしょう。ここではGnu getoptの利用方法を紹介します。

GNU getoptのJava実装を用いる

GNU getoptのMaven Repositoryからプロジェクトに必要なMavenやGradleのdependency記述方法を確認してください。

Mavenの場合の追加方法

<dependency>
  <groupId>gnu.getopt</groupId>
  <artifactId>java-getopt</artifactId>
  <version>1.0.13</version>
</dependency>

Gradleの場合の追加方法

implementation 'gnu.getopt:java-getopt:1.0.13'

サンプルプログラム

import gnu.getopt.Getopt;

public class GetOptSample
{
    static int count = 100;
    static boolean isDelete = false;
    static String name = "Default";

    public static void main(final String[] args) {
        Getopt options = new Getopt("Application Name", args, "c:dn:h");
        int c;
        while ( (c = options.getopt()) != -1) {
            switch (c) {
                case 'c':
                    count = Integer.parseInt(options.getOptarg());
                    break;
                case 'd':
                    isDelete = true;
                    break;
                case 'n':
                    name = options.getOptarg();
                    break;
                case 'h':
                default:
                    System.out.println("Usage: [-c count] [-d] [-n name]");
            }
        }

        System.out.println(String.format("%s: %d", "-c", count));
        System.out.println(String.format("%s: %b", "-d", isDelete));
        System.out.println(String.format("%s: %s", "-n", name));
    }
}

Getoptのコンストラクタ

コンストラクタ引数説明
第1引数プログラム名
第2引数引数パラメータの書式

引数パラメータの書式

  • 引数パラメータの書式は引数のキーのアルファベット一文字を一覧で記述します。
  • :を書いた場合、その前の引数は値を受け取ります。
  • 上記のサンプルの例では、dは値を受け取らない引数、cnは値を受け取る引数になります。

switchよるパラメータキーによる分岐

引数で渡されたパラメータのキーををint型の変数cに格納しています。getopt()はイテレータになっていて、次のパラメータのキー値を返します。次のパラメータのキー値が存在しなければ-1を返します。はswitchでこのcchar型のリテラルであるアルファベット一文字を比較します。char型の値はint値を持っているため、switchで比較することが可能です。

コマンドラインから以下のように実行します。

java GetOptSample -c 100 -d -n Sample -p

実行結果として以下を出力します。Getoptのコンストラクタで未定義または形式に不備のある引数が渡された場合、Getoptがエラーメッセージを出力します。

Application Name: invalid option -- p
-c: 100
-d: true
-n: Sample

コマンドライン引数の必須チェック

Getopt自体には引数自体の必須チェックが存在しないようです。そのため、引数自体がセットされていない場合の処理は自前で実装する必要があります。

参考

よかったらシェアしてね!
目次