Zakres widoczności zmiennych


Ten artykuł zakłada taką sytuację, że nigdy wcześniej nie programowałeś. Warto więc chyba wspomnieć o aspekcie widoczności zmiennych, o tym kiedy ich nazwy mogą się powtarzać, a kiedy się to nie uda.

Zmienne "globalne" w obrębie klasy

Charakteryzują się tym, że są widoczne w obrębie całej klasy, w której je utworzono. W rzeczywistości zmienna taka ma zakres ograniczony do pakietu - może z niej korzystać dowolna klasa w ramach tego samego pakietu. Taką zmienną nazywamy polem klasy.

class JakasKlasa {
    int poleKlasy = 5;

    void metoda1() {
        tutaj możesz użyć pola klasy
    }
}

Przede wszystkim możemy ich używać wewnątrz metod. Zazwyczaj właśnie w tym celu je tak deklarujemy - do komunikacji między metodami w obrębie jednej klasy. Mogłaby to też być stałą do której następują częste odwołania w różnych częściach kodu.

Kurs Java

Zmienne "lokalne" w ramach metod

Jak nie trudno się domyślić zakres widoczności, albo może lepiej nazwać to dostępnością, zmiennej to metoda, lub nawet konkretna pętla.

class JakasKlasa2{
    void metoda(){
        int zmiennaLokalna = 3;
    }

    int poleKlasy = zmiennaLokalna; //BŁĄD!
}

Oczywiście powyższy zapis jest błędny nie można się odwołać do zmiennej zadeklarowanej wewnątrz jakiejś metody poza nią samą. Zakres widoczności zmiennych wyznaczają zazwyczaj nawiasy klamrowe.

Zmienne wewnątrz instrukcji

Dodatkowo zmienne lokalne można deklarować nawet wewnątrz instrukcji sterujących, lub jako licznik w pętli.

class JakasKlasa3 {
    void metoda() {
        if (warunek) {
            int a = 5;
        }
        //tutaj zmienna "a" jest niewidoczna

        for (int i = 0; i < 10; i++) {  //zmienna obowiązuje tylko w pętli
            System.out.println("Java");
        }
    }
}

Co ciekawe nazwy zmiennych globalnych i lokalnych mogą być identyczne jednak o tym powiemy więcej przy programowaniu obiektowym i pojęciu przesłaniania. Nazwa "globalna" i "lokalna" nie powinna być interpretowana w Javie tak samo jak w innych językach programowania, prawidłowe będzie stwierdzenie "globalna w ramach klasy" w rozumieniu dostępności danej zmiennej w danej klasie (oddzielną kwestią jest dostępność zmiennej między klasami, lub pakietami).

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.

Poniżej znajdziesz archiwalne wpisy z czasów, gdy strona była jeszcze hobbystycznym blogiem.

Jan

Mam taki problem: co zrobić, żeby zmienna z metody była widoczna w całej klasie?:)

Slawek

stwórz sobie zmienną dostępną w całej klasie i przypisz do niej tą wartość?

DJ

Ja zrobiłem tak jak jest w przykładach i przy odpalaniu wyskakuje mi to : Exception in thread "main" java.lang.NoSuchMethodError: main Na necie znalazłem to : public class Lokalne { public String my_member_variable = "somedata"; public static void main (String args[]) { Lokalne yay = new Lokalne(); // Access member variable of demo System.out.println ("This WON'T generate an error" + yay.my_member_variable ); } } I teraz działa. Dlaczego to co napisałeś mi nie działa?: D

Slawek

W przykładach są klasy, które się kompilują, ale żadna z nich nie zawiera metody main() od której rozpoczyna się działanie programu, więc otrzymujesz wyjątek, że jej nie odnaleziono. Dodam tu w sumie jakiś przykład i zadanie, ale na razie brak czasu na cokolwiek :)

Krzysiek

Dzieki kolo wielki szacun z to co robisz!!! Chce zostac programista i dlugo szukalem takiego kursu jak ten.Wszedzie bd go polecal. THX

andrew

Witam. Jak w poniższym przykładzie użyć zmiennej globalnej "i", aby jej nie deklarować przy każdym użyciu pętli, oraz zamiast zmiennej "z" też użyć zmiennej "i" ? import java.util.Scanner; public class Zad1_113{ public static void main(String[] args){ System.out.println("Podaj rozmiar calkowity tablicy"); Scanner in=new Scanner(System.in); int n=in.nextInt(); int[] tab=new int[n]; for (int i=0;i&lt;n;i++) { System.out.println(&quot;podaj &quot; +(i+1)+&quot; element tablicy&quot;); Scanner in1=new Scanner(System.in); tab[i]=in1.nextInt(); } int i=0; while( i&lt;tab.length){ System.out.println(+(i+1)+&quot; element tablicy to: &quot;+tab[i]); i++;} int z=0; do{ System.out.println(+(z+1)+ &quot;element w tablicy to: &quot;+tab[z]); z++; } while(z&lt;n); } }

Witek

Witam Zaraz pod metodą main( ), możesz zadeklarować zmienne globalne (choć nie koniecznie) np.: <code> public static void main(String[] args){ int i; int z; </code> ,które nie są zainicjowane. Następnie w usuwasz z petli for typ danej czyli int, a zostawiasz tylko " i " <code> for( i = 0; i &lt; n ; i ++) // tu &quot; i &quot; jest inicjowane, </code> dalej przed pętla While " i " , ma przypisaną nową wartość czyli zero " i = 0; ", a przed pętlą do { ...... } while, zmiennej „ z „ przypisujesz wartość 0, " z = 0;" I to wszystko, twój program po wprowadzeniu poprawek takich jak założyłeś u mnie działa, jak będziesz chciał kod to mogę go wkleić.

andrew

Witam. Proste i logiczne jak budowa cepa. Robiłem tak i już wiem dlaczego nie działało - trzeba pamiętać o wyzerowaniu "i", gdyż po pobraniu elementów tablicy przed pętlami "do" i "while" ma ona wielkość = zmiennej "n". Po zmianie "z" na "i" wszystko huula. Dzieki Witek za pomoc.

Witek

Nie ma za co.

Tomek

Pisze te programy w Eclipse43 i w JakasKlasa3 wyskakuje mi blad przy lini: if (warunek){ dlaczego? Pytanie moze bardzo smieszne ale przy moim poziomie "zaawansowania" to prawdziwy problem

Daniel

Dlatego, że przez „warunek” Kolega miał na myśli np. ( a &gt; 5 ) Pozdrawiam!

Daniel

Przepraszam za małe zamydlenie :-D Ale źle spojrzałem na kod ;-) Zatem...: if( b &lt; 3) { int a = 5; } Czyli jeśli b jest mniejsze od 3 to a przypisana zostanie wartość 5. Jeśli nie to nie ;-)

bartek

Jeszcze takie pytanie bo nie do końca zrozumiałem. Najpierw piszesz, że zmienna globalna jest dostępna tylko w danej klasie i jej metodach, a poniżej że w pakiecie ? Przecież pakiet może zawierać wiele klas (plików typu class). Jak ewentualnie zrobić, żeby zmienna była dostępna we wszystkich klasach danego pakietu ?

Sławek Ludwiczak

Hej. Jeśli klasy są w jednym pakiecie, to zmienna będzie dostępna w drugim pliku, ale w tym drugim pliku musisz utworzyć najpierw utworzyć obiekt pierwszej klasy, a do zmiennych odwoływać się za pomocą operatora kropki. Nazwa "zmienna globalna" w tej lekcji odnosi się do tego, że masz do niej dostęp z każdego miejsca tej klasy. Masz do niej także dostęp z innych klas, w których utworzysz instancję tej klasy. Jeśli będziesz się chciał odwołać natomiast do pola tej klasy z innego pakietu to będzie to niemożliwe, ponieważ klasy w przykładach mają jedynie zasięg domyślny (nie mają zapisu <strong>public</strong> class Nazwa {...}) Jeżeli nadal jest problem i potrzebujesz dłuższej odpowiedzi z przykładem, zapraszam do zadania pytania na forum.