2013-07-17 14 views
48

Próbowałem tego i otrzymałem dziwne zachowanie od JAVA, czy ktoś może mi to wyjaśnić?Zachowanie parametru Java 3 kropki (varargs) po przekazaniu bez argumentów lub wartości zerowej

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

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

Wtedy mam przypadek testowy:

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

pytanie brzmi, czy mogę zadzwonić testNull() bezpośrednio z parametrem null, dostanę true powrotem, ale jeśli rozmowy callTestNull() z null, który wzywa testNull(), to mówi mi, że parametr nie jest pusty, ale pusta tablica.

+0

Jak znaleźć tablicę jest pusta? –

+0

nazywana również elipsą –

+4

Mam na myśli terminologię Java. Ale tak, postać "..." jest rzeczywiście nazywana elipsą. Więcej informacji na temat programowania tutaj https: //en.wikipedia.org/wiki/Ellipsis_ (programming_operator) – eldris

Odpowiedz

50

pytanie brzmi, czy mogę zadzwonić testNull() bezpośrednio z parametrem null, będę się prawdziwy powrót, ale jeśli callTestNull call() z null, która wywołuje testNull(), to mówi mi, że parametr nie jest pusty, ale pusta tablica.

Tak. Jeśli wywołasz go z argumentem z typu kompilacji z String, kompilator wie, że nie może być String[], więc zawija go w tablicy ciągów. Więc tak:

String x = null; 
testNull(x); 

odpowiada:

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

W tym momencie (myląco nazwany) string parametr będzie mieć niezerową wartość - zamiast tego, będzie odnosić się do tablicy rozmiar 1, którego jedynym elementem jest odwołanie zerowe.

Jednakże, jeśli użyjesz literału null bezpośrednio w wywołaniu metody, można go bezpośrednio przekonwertować na String[], więc nie wykonuje się owijania.

Z JLS section 15.12.4.2:

Jeśli sposób ten jest wywoływany jest zmienny sposób arity m koniecznie ma n> 0 parametrów formalnych. Ostateczny formalny parametr m koniecznie ma typ T [] dla jakiegoś T, a m jest koniecznie wywoływany z k> 0 faktycznymi wyrażeniami argumentów.

Jeśli m jest wywoływane z wyrażeniami rzeczywistymi argumentów k ≠ n, lub jeśli m jest wywoływane z k = n rzeczywistymi argumentami wyrażenia , a typ wyrażenia k'th nie jest zgodny z T [], wówczas lista argumentów (e1, ..., en-1, en, ..., ek) jest oceniana tak, jakby była zapisana jako (e1, ..., en-1, new | T [] | {en, ..., ek}), gdzie | T [] | oznacza usunięcie (§4.6) T [].

(podkr.)

Bit Mam podkreślił Dlatego owijania tylko dzieje, gdy typ kompilacji argumentu jest String, nie null typu.

Powiązane problemy