回答は以下を参照してください -- 士気: 決して.split()
単独で電話をかけないでください。正常な動作が必要な場合は、常に長さ引数に -1 を指定してください。でも0じゃない!
のjavadocにPattern.split()
は、次のように記載されています。
このメソッドによって返される配列には、このパターンに一致する別のサブシーケンスで終了するか、入力シーケンスの最後で終了する入力シーケンスの各部分文字列が含まれます。
このコードを目撃してください:
private static final Pattern UNDERSCORE = Pattern.compile("_");
public static void main(final String... args)
{
System.out.println(UNDERSCORE.split("_").length);
}
ここで、javadoc を参照すると、配列には次のいずれか (引用) の入力の部分文字列が含まれている必要があります。
- 「このパターンに一致する別のサブシーケンスによって終了する」: まあ、アンダースコアの直前の空の文字列 (
UNDERSCORE
明らかに一致する) があります。 - または「入力シーケンスの最後で終了します」: アンダースコアの直後の空の文字列もあります。
それでも、上記のコードは0
. なんで?これは既知のバグですか? ( imnsho はい、以下を参照してください.split()
) が契約に従わない他のケースにはどのようなものがありますか? (繰り返しますが、以下を参照してください)
THE ANSWER (この説明テキストのすぐ下)
を使用する場合Pattern
、引数が 1.split()
つのメソッドは0
、引数として引数が 2 つのメソッドを呼び出すのと同じです。
そして、ここにバグがあります。引数が 0 の場合、配列の末尾から最初の空でない要素までのすべての空の文字列が結果から削除されます。
これを読む前に、脳死状態の設計決定が何であるかを知らなかった場合は、今すぐわかります。そして、これがデフォルトの動作であることはなおさら危険です。
解決策は、メソッドの完全な形式を常に使用し.split()
、負の長さの引数を与えることです。ここでは、-1 が選択されています。この場合、正常に.split()
動作します。
private static final Pattern UNDERSCORE = Pattern.compile("_");
public static void main(final String... args)
{
System.out.println(UNDERSCORE.split("_").length);
System.out.println(UNDERSCORE.split("__").length);
System.out.println(UNDERSCORE.split("_x_").length);
System.out.println(UNDERSCORE.split("_", -1).length);
System.out.println(UNDERSCORE.split("__", -1).length);
System.out.println(UNDERSCORE.split("_x_", -1).length);
}
出力:
0 # BUG!
0 # BUG!
2 # BUG!
2 # OK
3 # OK
3 # OK