私はこれを試して、Javaから奇妙な動作を得ました、誰かがこれを私に説明できますか?
_boolean testNull(String... string) {
if(string == null) {
return true;
} else {
System.out.println(string.getClass());
return false;
}
}
boolean callTestNull(String s) {
return testNull(s);
}
_
次に、テストケースがあります:
_ @Test
public void test_cases() {
assertTrue(instance.testNull(null)); // NULL
assertFalse(instance.testNull()); // NOT NULL
assertFalse(instance.callTestNull(null)); // NOT NULL
}
_
問題は、パラメータnull
でtestNull()
を直接呼び出すと、true
が返されますが、null
でcallTestNull()
を呼び出す場合ですtestNull()
を呼び出す_は、パラメーターがnullではなく空の配列であることを通知します。
問題は、パラメータnullで直接testNull()を呼び出すと、trueが返されることですが、testNull()を呼び出すnullでcallTestNull()を呼び出すと、パラメータがnullではなく空の配列であることがわかります。
はい。 compile-time typeof String
の引数で呼び出すと、コンパイラーはca n'tString[]
であるため、文字列配列でラップします。したがって、この:
String x = null;
testNull(x);
以下と同等です:
String x = null;
testNull(new String[] { x });
この時点で、(誤解を招く名前の)string
パラメーターはnull以外の値を持ちます。代わりに、唯一の要素がnull参照であるサイズ1の配列を参照します。
ただし、メソッド呼び出しでnull
リテラルを直接使用すると、String[]
に直接変換できるため、ラッピングは実行されません。
呼び出されるメソッドが可変アリティメソッドmである場合、必然的にn> 0の仮パラメータを持ちます。 mの最終的な仮パラメータは、何らかのTに対して必ず型T []を持ち、mは必然的にk≥0の実引数式で呼び出されます。
Mがk≠nの実引数式で呼び出されている場合、またはm = k = nの実引数式で呼び出されており、k番目の引数式の型が代入互換でない場合T []を使用すると、引数リスト(e1、...、en-1、en、...、ek)は、(e1、.. 。、en-1、new | T [] | {en、...、ek})、ここで| T [] | T []の消去(§4.6)を示します。
(エンファシス鉱山。)
強調したのは、引数のコンパイル時の型がnull型ではなくString
であるときにonlyのみがラップされる理由です。