2013-07-03 14 views
13

Poniższy kod Java nie jest kompilowany.Dlaczego nie można zadeklarować zmiennych w instrukcji if?

int a = 0; 

if(a == 1) { 
    int b = 0; 
} 

if(a == 1) { 
    b = 1; 
} 

Dlaczego? Nie może istnieć żadna ścieżka kodu prowadząca do programu przypisującego 1 do b bez zadeklarowania jej jako pierwszej.

Przyszło mi do głowy, że zmienny zakres b może być ograniczony do pierwszego oświadczenia , ale wtedy nie rozumiem dlaczego. Co, jeśli naprawdę nie chcę deklarować b niepotrzebnie, aby poprawić wydajność? Nie lubię, gdy zmienne pozostały niewykorzystane po deklaracji.

(Można argumentować, niż mogłem po prostu zadeklarować B w drugim if oświadczenie, w takim przypadku, proszę sobie wyobrazić, że może być w pętli gdzieś indziej.)

+0

bo b ogłosił w pierwszym czy blok i niedostępne z bloku, deklarują B z –

+1

Co przyszło ci do głowy ma rację. Twoja zmienna b jest tylko w zakresie dla tego konkretnego nawiasu klamrowego. – Thihara

+0

Przeczytaj wyjaśnienie ** CAŁE **. – Aeronth

Odpowiedz

10

Dlaczego? Nie może istnieć żadna ścieżka kodowa prowadząca do programu przypisującego 1 do b bez zadeklarowania jej jako pierwszej.

Masz rację, ale kompilator tego nie wie. Kompilator nie wykonuje kodu. Kompilator tłumaczy tylko do kodu bajtowego bez oceniania wyrażeń.

26

Zmienne mogą być deklarowane wewnątrz warunkowa komunikat. Jednak próbujesz uzyskać dostęp do b w innym zakresie.

Kiedy deklarujesz b tutaj:

if(a == 1) { 
    int b = 0; 
} 

to tylko w zakresie do końca }.

Dlatego, gdy przyjdziesz do tej linii:

b = 1; 

b nie istnieje.

1

To wszystko dotyczy zakresu zmiennej java.

Musisz zdefiniować variable na zewnątrz, jeśli statement, aby móc go używać na zewnątrz.

int a = 0; 
int b = 0; 

if(a == 1) { 
    b = 1; 
} 

if(a == 1) { 
    b = 2; 
} 

Patrz Blocks and Statements

1

ponieważ gdy b wykracza poza zakres w pierwszym, jeżeli (a == 1), a następnie zostanie ona usunięta i nie występuje już w stosie, a zatem nie mogą być stosowane w następna, jeśli instrukcja.

5

Ten { } definiuje zakres blokowy. Wszystko zadeklarowane między {} jest lokalne dla tego bloku. Oznacza to, że nie możesz ich używać poza blokiem. Jednak Java nie zezwala na ukrywanie nazwy w zewnętrznym bloku przez nazwę w wewnętrznej. To co JLS mówi:

Zakres deklaracji zmiennej lokalnej w bloku (§14.2) to reszta bloku, w którym pojawia się deklaracja, wychodząc z własnym inicjatora (§14.4) i tym wszelkie dalszych deklaratorów po prawej stronie w deklaracji o deklaracji zmiennej lokalnej.

Nazwa zmiennej lokalnej v może nie zostać ponownie zadeklarowana jako zmienna lokalna bezpośrednio otaczającej metody, konstruktora lub bloku inicjalizacyjnego w zakresie v lub wystąpił błąd podczas kompilacji.

2

Jest to zmienna lokalna i jest ograniczona do zakresu {}.

Spróbuj tego here.

2

zostały uznane b zmiennej wewnątrz jeżeli blok, który nie jest dostępny z boku if bloku i jeśli chcesz uzyskać dostęp, a następnie umieścić na zewnątrz, jeśli blok

1

Jeśli zadeklarujesz zmienną wewnątrz bloku, to ograniczenie limitów zmiennych do konkretnego bloku, w którym zostało zadeklarowane.

UWAGA: Tylko statyczne zmienne mają dostęp z dowolnego miejsca w programie.

w was kodu:

int a = 0; 

if(a == 1) { 
    int b = 0; 
} 

if(a == 1) { 
    b = 1; 
} 

zmienna „a” można uzyskać w dowolnym if jako jej oświadczyć na zewnątrz bloku, ale zmienna „b” jest zadeklarować wewnątrz jeśli stąd ogranicza jej zastosowanie na zewnątrz bloku.

Jeśli chcesz użyć "b" poza instrukcją if, musisz zadeklarować ją tam, gdzie zadeklarowałeś zmienną "a".

1
int a = 0; 

if(a == 1) { 
int b = 0; // this int b is only visible within this if statement only(Scope) 
} 

if(a == 1) { 
b = 1; // here b can't be identify 
} 

trzeba zrobić w następujący sposób, aby naprawić błąd

int a = 0; 
    int b = 0; 
    if(a == 1) { 
     b=0; 
    } 
    if(a == 1) { 
     b = 1; 
    } 
2

Zakres b jest blok jest zadeklarowane, to znaczy, że jeśli pierwszy. Dlaczego to jest takie? Ponieważ ta zasada ustalania zakresu (zakres leksykalny) jest łatwa do zrozumienia, łatwa do wdrożenia i zgodna z zasadą najmniejszego zaskoczenia.

Jeżeli B miały być widoczne w drugim, jeżeli:

  • kompilator musi wnosić równoważne, jeśli gałęzie i połączenie ich w jeden zakres (trudno wprowadzić);
  • zmiana warunku w losowej instrukcji if może spowodować, że niektóre zmienne będą widoczne, a inne ukryte (trudne do zrozumienia i źródło zaskakujących błędów).

Żaden rozsądny język nie ma tak skomplikowanej reguły ustalania zakresu.

w.r.t. wydajność - deklarowanie dodatkowej zmiennej ma znikomy wpływ na wydajność. Zaufaj kompilatorowi! Przydzieli efektywnie rejestry.

+0

Matlab ma taką regułę ustalania zasięgu, obawiam się, jej piekielne. (jest też dynamiczny, dlatego przede wszystkim potrafi sobie poradzić z tym szaleństwem). Powiedziałeś "nie ma normalnego ** języka", wystarczy, wycofuję mój komentarz. –

+0

Tak, powiedziałem "rozsądny";) Nie wiedziałem jednak o tym szaleństwie z Matlab. –

1

Właśnie przez wzgląd na kompletność: ten działa tak samo (wyjaśnienie jest określenie zakresu, zobacz inne odpowiedzi)

int a = 0; 

if(a == 1) { 
    int b = 0; 
} 

if(a == 1) { 
    int b = 1; 
} 

Z powodu scopingu, b będzie dostępna wewnątrz if tylko. To, co mamy tutaj, to w rzeczywistości dwie zmienne, z których każda jest dostępna w ich zasięgu.

0

Zakres zmiennej b ma wartość tylko do zakończenia bloku if, ponieważ jest to miejsce, w którym zadeklarowano zmienną. Dlatego nie można uzyskać do niego dostępu w następnym bloku. To jest dla alokacji pamięci, w przeciwnym razie byłyby ALOT zmiennych unoszących się w pamięci.

int a = 0; 

if(a == 1) { 
    int b = 0;  
} //b scope ends here 

if(a == 1) { 
    b = 1; //compiler error 
}