2015-03-11 11 views
10

Mam metodę mającą parametr tablicy jak:Pokój initializer klamra i tablica

public static void foo(int[] param) { 
    // Some code 
} 

A także mogę wywołać metodę pisząc jak

foo(new int[3]); 

Normalnie, zadeklarować i zainicjować tablicę przez nowy operator lub inicjator podwójnych nawiasów klamrowych, taki jak {1, 2, 3}. Na przykład: int[] foo = new int[3];lubint[] foo = {1, 2, 3};.

Ale nie można użyć inicjatora podwójnego nawiasu jako parametru dla metody. {} jest dostępna tylko do tworzenia obiektu tablicy.

Oto moje pytanie: czy są jakieś różnice między nowym operatorem a {}? Jeśli jest, co to jest?

+0

dzięki za komentarz, przerażające. i to jest właśnie moja uwaga. foo ({1, 2, 3}) nie działa ... –

+4

'foo (nowy int [] {1, 2, 3})' działa – Eran

+0

@Eran tak, ale pytanie brzmi: dlaczego int [] i = {1,2,3}; działa, ale nie foo ({1,2,3}); – Subler

Odpowiedz

17

{} jako część int foo[] = {1, 2, 3}; to, co jest określane jako inicjalizacji nawiasów, a jest skrótem dla int foo[] = new int[]{1, 2, 3}; ponieważ new int[] można wywnioskować z lewego skrzydła.

W drugim przypadku foo({1, 2, 3}); nie można wnioskować o tym, co zamierzamy określić, ponieważ nie ma wskazania, co oznacza {1, 2, 3}, więc kompilator narzeka.

Po przepisaniu go jako foo(new int[]{1, 2, 3}); mówisz kompilatorowi, co ma reprezentować element w {}.

Kompilator nie będzie (i nie będzie próbował) interpretować automatycznie wyrażenia {}, dopóki nie zostanie dopasowany - co może prowadzić do potencjalnych niejasności.

Istnieje również this question, który wydaje się pokrywać dokładnie ten sam grunt.

Jak wspomniano przez @benzonico, jest częścią language specification, ponieważ jest to obsługiwana składnia, która nie uwzględnia jej użycia w wywołaniu metody.

5

Aby ukończyć drugą odpowiedź, można rzucić okiem na JLS 8 10.6: można zobaczyć, że w gramatyce inicjator zmiennej jest albo wyrażeniem LUB (wyłącznym) inicjatorem tablicy (który nie jest wyrażeniem, a zatem nie może użyj podczas wywoływania metody).