varargs vararg parametros indefinidos argumentos java variadic-functions ellipsis

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.