torutkのブログ

ソフトウェア・エンジニアのブログ

可変長引数をObject型配列に変換

Javaのロギングフレームワークの1つ、slf4jのAPIは、

void debug(String format, Object arg)
void debug(String format, Object arg1, Object arg2)
void debug(String format, Object[] argArray)

のようになっており、

LOGGER.debug("input:{}, output:{}", in, out);

のように使えますが、パラメータが3つ以上の場合は

LOGGER.debug("input:{}, output:{}, status:{}", new Object[] { in, out, status });

のように、Object型配列にする必要があります。

注記)SLF4J Ver.1.7.0から可変長引数を使ったAPIが追加され、パラメータが3つ以上でもObject型配列にする必要はなくなりました。

Javaでは、Ver.5(Java 2 SE 5.0 "Tiger")から、可変長引数が導入されているので、

void debug(String format, Object... args)

のようにAPIが提供されていたとすれば、

LOGGER.debug("input:{} output:{} status:{} sequence{}", in, out, status, num);

のように呼び出せるのですが、残念ながら可変長引数の導入はslf4jのバグNo.31 "Varargs for Logger methods"によると、Java 1.4との互換性維持のため実施しない、ということです。

このバグに対するコメント(2011/3/19)に、複数パラメータのときのちょっとした工夫が紹介されており、以下に引用します。

package util;

public class Util {
  public static Object[] va(Object... args) {
    return args;
  }
}

package foo;
import static util.Util.va;
...
 logger.info("a {}, b {}, c c {}", va("A", "B", "C"));
...

これなら、すこし記述が楽になりますね。

java.util.loggingでも、

void log(Level level, String msg, Object param1)
void log(Level level, String msg, Object[] params)

と似たAPIがありますので、こちらでも使えるテクニックです。