2013-07-17 11 views
48

Ho provato questo e ottenere comportamenti strani da JAVA, qualcuno può spiegarlo per me?Comportamento di parametro (varargs) di Java 3 punti quando non viene passato alcun argomento o null

boolean testNull(String... string) { 
    if(string == null) { 
     return true; 
    } else { 
     System.out.println(string.getClass()); 
     return false; 
    } 
} 

boolean callTestNull(String s) { 
    return testNull(s); 
} 

Poi ho test case:

@Test 
    public void test_cases() { 
     assertTrue(instance.testNull(null)); // NULL 
     assertFalse(instance.testNull()); // NOT NULL 
     assertFalse(instance.callTestNull(null)); // NOT NULL 
    } 

La domanda è se chiamo testNull() direttamente con il parametro null, mi metterò true indietro, ma se chiamata callTestNull() con null, che chiama testNull(), è mi dice che il parametro non è nullo, ma array vuoto.

+0

Come fai a sapere che l'array è vuoto? –

+0

chiamato anche ellissi –

+4

intendevo in termini di terminologia Java. Ma sì, il personaggio "..." è effettivamente chiamato ellissi. Maggiori informazioni sulla programmazione usate qui https: //en.wikipedia.org/wiki/Ellipsis_ (programming_operator) – eldris

risposta

50

la domanda è se chiamo TestNull() direttamente con il parametro null, mi metterò vero indietro, ma se chiamata callTestNull() con null, che chiama TestNull(), mi dice il parametro non è nullo, ma array vuoto.

Sì. Se lo chiami con un argomento con di di , il compilatore sa che non può essere un String[], quindi lo avvolge all'interno di un array di stringhe. Quindi questo:

String x = null; 
testNull(x); 

è equivalente a:

String x = null; 
testNull(new String[] { x }); 

A questo punto, il (erroneamente nome) parametro string avrà un valore non nullo - invece, si farà riferimento ad una matrice di dimensione 1 il cui unico elemento è un riferimento null.

Tuttavia, quando si utilizza il valore letterale null direttamente nella chiamata al metodo, questo è direttamente convertibile in String[], quindi non viene eseguito alcun ritorno.

Da JLS section 15.12.4.2:

Se il metodo essendo richiamato è una variabile metodo arity m, ha necessariamente n> 0 parametri formali. Il parametro formale finale di m ha necessariamente il tipo T [] per alcuni T, e m è necessariamente invocato con k ≥ 0 espressioni di argomento reali.

Se m viene invocato con k ≠ n espressioni di argomento effettive, o, se m viene invocato con k = n espressioni di argomento effettive e il tipo di espressione di argomento k'th non è assegnabile a T [], quindi l'elenco degli argomenti (e1, ..., en-1, en, ..., ek) viene valutato come se fosse scritto come (e1, ..., en-1, new | T [] | {en, ..., ek}), dove | T [] | denota la cancellazione (§4.6) di T [].

(l'enfasi è mia.)

Il bit che ho sottolineato è il motivo per il confezionamento solo accade quando il tipo in fase di compilazione della tesi è String, non il tipo nullo.

Problemi correlati