J'ai essayé cela et j'ai obtenu un comportement bizarre de Java, quelqu'un peut-il expliquer cela pour moi?
boolean testNull(String... string) {
if(string == null) {
return true;
} else {
System.out.println(string.getClass());
return false;
}
}
boolean callTestNull(String s) {
return testNull(s);
}
Ensuite, j'ai un cas de test:
@Test
public void test_cases() {
assertTrue(instance.testNull(null)); // NULL
assertFalse(instance.testNull()); // NOT NULL
assertFalse(instance.callTestNull(null)); // NOT NULL
}
La question est de savoir si j'appelle testNull()
directement avec le paramètre null
, je récupérerai true
, mais si j'appelle callTestNull()
avec null
, qui appelle testNull()
, il me dit que le paramètre n'est pas nul, mais un tableau vide.
La question est de savoir si j'appelle testNull () directement avec le paramètre null, je reviendrai vrai, mais si j'appelle callTestNull () avec null, qui appelle testNull (), il me dit que le paramètre n'est pas nul, mais un tableau vide.
Oui. Si vous l'appelez avec un argument avec un type de compilation de String
, le compilateur sait que ne peut pas être un String[]
, il l'enveloppe donc dans un tableau de chaînes. Donc ça:
String x = null;
testNull(x);
est équivalent à:
String x = null;
testNull(new String[] { x });
À ce stade, le paramètre (nommé de manière trompeuse) string
aura une valeur non nulle - à la place, il fera référence à un tableau de taille 1 dont le seul élément est une référence nulle.
Cependant, lorsque vous utilisez le littéral null
directement dans l'appel de méthode, il est directement convertible en String[]
, donc aucun habillage n'est effectué.
Si la méthode invoquée est une méthode d'arité variable m, elle a nécessairement n> 0 paramètres formels. Le paramètre formel final de m a nécessairement le type T [] pour certains T, et m est nécessairement invoqué avec k ≥ 0 expressions d'argument réelles.
Si m est invoqué avec k ≠ n expressions d'argument réelles, ou, si m est invoqué avec k = n expressions d'argument réelles et que le type de la kième expression n'est pas compatible avec les affectations avec T [] , alors la liste d'arguments (e1, ..., en-1, en, ..., ek) est évaluée comme si elle était écrite comme (e1, .. ., en-1, nouveau | T [] | {en, ..., ek}), où | T [] | dénote l'effacement (§4.6) de T [].
(Je souligne.)
Le bit que j'ai souligné est la raison pour laquelle le wrapping seulement se produit lorsque le type de compilation de l'argument est String
, pas le type null.