parametros - Comportamiento del parámetro de puntos de Java 3(varargs) cuando no se pasan argumentos o es nulo
vararg kotlin (1)
Probé esto y obtengo un comportamiento extraño de JAVA. ¿Puede alguien explicarme esto?
boolean testNull(String... string) {
if(string == null) {
return true;
} else {
System.out.println(string.getClass());
return false;
}
}
boolean callTestNull(String s) {
return testNull(s);
}
Entonces tengo caso de prueba:
@Test
public void test_cases() {
assertTrue(instance.testNull(null)); // NULL
assertFalse(instance.testNull()); // NOT NULL
assertFalse(instance.callTestNull(null)); // NOT NULL
}
La pregunta es si llamo a testNull()
directamente con el parámetro null
, obtendré true
, pero si llamo a callTestNull()
con null
, que llama a testNull()
, me dice que el parámetro no es nulo, sino una matriz vacía.
La pregunta es si llamo a testNull () directamente con el parámetro nulo, obtendré true, pero si llamo a callTestNull () con null, que llama a testNull (), me dice que el parámetro no es nulo, sino una matriz vacía.
Sí. Si lo llama con un argumento con un tipo de String
de tiempo de compilación , el compilador sabe que no puede ser una String[]
, por lo que lo envuelve dentro de una matriz de cadenas. Así que esto:
String x = null;
testNull(x);
es equivalente a:
String x = null;
testNull(new String[] { x });
En este punto, el parámetro de string
(con nombre engañoso) tendrá un valor no nulo; en cambio, se referirá a una matriz de tamaño 1 cuyo único elemento es una referencia nula.
Sin embargo, cuando usa el literal null
directamente en la llamada al método, eso se puede convertir directamente a String[]
, por lo que no se realiza ningún ajuste.
De la sección 15.12.4.2 de JLS :
Si el método que se invoca es un método de aridad variable m, necesariamente tiene n> 0 parámetros formales. El parámetro formal final de m necesariamente tiene el tipo T [] para algunos T, y m se invoca necesariamente con k ≥ 0 expresiones de argumentos reales.
Si m se está invocando con k n n expresiones de argumento reales, o si m se está invocando con k = n expresiones de argumento real y el tipo de expresión de argumento k''th no es compatible con T [] , entonces la lista de argumentos (e1, ..., en-1, en, ..., ek) se evalúa como si estuviera escrito como (e1, ..., en-1, nuevo | T [] | {en, ... , ek}), donde | T [] | denota el borrado (§4.6) de T [].
(Énfasis mío.)
Lo que he enfatizado es por qué el ajuste solo ocurre cuando el tipo de argumento en tiempo de compilación es String
, no el tipo nulo.