String#replaceFirst より StringUtils#replace を使う

DAO層で発行しているSQLのトレースをしているのだが、パラメータが "?" のまま出力されると不便なので、"?"をバインドされるパラメータに置換してからSQL文を出力するデバッグルーチンを書いたら、

java.lang.IllegalArgumentException: Illegal group reference

とかいって落ちた。
これは String#replaceFirst で置換していたのが原因。

String#replaceFirst(String regex, String replacement)

このメソッドは、第二引数 replacement に $ が含まれていると正規表現特殊文字だと思って「$hoge て何よ?そんなグループないよ」という例外を投げる。
replacementに $ が含まれていたら \\$ に置換すれば落ちなくなるが、置換するために置換するというのも変な話。


結論、Stringクラスの replaceXXXX は、第二引数が動的に決まる時は使わないのがよい。
単純な置き換えには Jakarta Commons Lang の StringUtils#replace を使うのがよい。