可変長引数のループで ヌルポ発生
先日とあるプロジェクトで、可変長引数を for - each している箇所でヌルポになっていた。
実際にはずっと複雑だが、簡単に書くと以下のような for ループでのヌルポ。
public void method(String... args) { for (String string : args) { // java.lang.NullPointerException // ... } }
この10年 可変長引数が null
を受け取るなんて。
可能性すら考えるまでもなく問題なしと思い込んでいた。
普通の呼び出し
普通に呼び出すと、
method(); method("hello"); method("hello", "world");
それぞれ長さが 0, 1, 2 の文字列配列が渡る。
変数でも、null
の変数だと、
String str = "hello"; method(str); str = null; method(str);
長さ1の配列と、長さ0の配列になりヌルポにはならない。
なんだ!? これ
何をしたかったのか謎だが、あえてリテラルで null
渡してた。
method(null);
java.lang.NullPointerException
になる。
まぁ、そりゃそうか。
念のため
以下の可変長引数は、
public void method(String... args) { }
コンパイル後は以下と同じになる。
public void method(String[] args) { }
以下のような呼び出しは、
method("hello");
コンパイル後は以下と同じになる。
method(new String[] { "hello" });
とすると先の例は、コンパイル後のコードは以下になる。
String str = null; method(new String[] { str });
直接 null
渡せば、ヌルポ。
method(null);
どうしても null を渡したい場合
以下のようにキャストすればヌルポにはならない。
method((String) null);
配列としてキャストすると、
method((String[]) null);
これはヌルポ。
まとめ
でも普通に考えて、null チェックはしないかな。