Stałe

„Amigo, czy wiesz, że w Javie nie wszystkie zmienne można zmienić?”

„Jak to, Kim? Rzeczywiście, samo słowo„ zmienna ”mówi o zmianie”.

„Co do tego nie ma wątpliwości. Podobnie jak wiele innych języków programowania, Java ma stałe , czyli zmienne, których wartości nie można zmienić . A samo słowo „stała” mówi o stałości”.

— A po co one są?

„Zwykle są one używane do jakiejś podstawowej rzeczy, takiej jak liczba Pilub liczba dni w miesiącach w roku. To powiedziawszy, w zasadzie programista może uczynić dowolną zmienną stałą, jeśli zdecyduje, że robienie tego tak jest konieczne”.

„Masz na myśli imię, kolor samochodu lub nazwę dnia tygodnia?”

„Masz dobry pomysł. Wszystko, czego nie powinno się zmieniać”.

„A jak te stałe wyglądają w Javie?”

„Java ma dla nich specjalne słowo kluczowe: final. Tworzenie niezmiennej zmiennej wygląda tak samo, jak tworzenie zwykłej. Jedyna różnica polega na tym, że przed typem zmiennej należy napisać słowo final, takie jak to:

final Type name = value;

„Co się stanie, jeśli utworzysz stałą, a następnie spróbujesz przypisać jej inną wartość?”

„To jest właściwe pytanie! A prawidłowa odpowiedź jest następująca: jeśli spróbujesz przypisać inną wartość do zmiennej final, twój program po prostu się nie skompiluje”.

„Co się stanie, jeśli zadeklarujesz finalzmienną, ale nie przypiszesz jej wartości?”

„Nie ma sensu tego robić, więc nie jest to również dozwolone w Javie. Zmienna finalmusi być zainicjowana podczas deklarowania, to znaczy należy przypisać jej wartość. Jest jeden wyjątek od tej reguły: możesz przenieść inicjalizację statyczną zmienną klasy w konstruktorze, ale o tym dowiesz się później.

To powiedziawszy, nie wszystko, co jest, finaljest stałą. Aby zmniejszyć liczbę słów kluczowych, programiści Javy używają tego słowa finalnie tylko do deklarowania stałych. finalMoże to dotyczyć również metod, a nawet klas. Metod zadeklarowanych jako finalnie można przesłonić, a klasa zadeklarowane jako finalnie mogą być dziedziczone”.

„Uch… Przekreślony? Odziedziczony? W jakim języku teraz mówisz?”

„Język programowania obiektowego. Wkrótce się do niego przekonasz. Do tego czasu po prostu ciesz się piękną terminologią.”

„W porządku. Więc finalmożna je umieścić przed zmiennymi, klasami i metodami, a to słowo kluczowe czyni je w pewnym sensie niezmiennymi?”

„Tak. Ponadto finalmodyfikator można dodać przed dowolnymi zmiennymi: zmiennymi lokalnymi, parametrami metod, polami klas i statycznymi zmiennymi klas.

„Oto ważna rzecz do zapamiętania: finalprzed nazwą zmiennej jest po prostu ochrona przed wszelkimi zmianami tej zmiennej . Jeśli zmienna przechowuje odniesienie do obiektu, to obiekt nadal można zmienić”.

„Nie do końca rozumiem”.

„Zrozumiesz naprawdę wkrótce. Oto przykład:

final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
Tworzymy tablicę.

Nie jest to dozwolone: ​​zmienna datajest zadeklarowana jako final.

Ale możesz to zrobić.
A także to.

„Rozumiem. To trudne”.

Stałe globalne

„Jak myślisz, czym są stałe globalne?”

„Domyślam się, że stałe globalne są prawdopodobnie jak zmienne globalne, tylko stałe?”

„Dokładnie. Jeśli chcesz zadeklarować stałe globalne w swoim programie, utwórz zmienne klasy statycznej i zrób z nich publici final. Istnieje specjalny styl nazw takich zmiennych: są one pisane wielkimi literami, ze znakiem podkreślenia używanym do oddzielne słowa.

Przykłady:

class Solution
{
   public static final String SOURCE_ROOT = "c:\\projects\\my\\";
   public static final int DISPLAY_WIDTH = 1024;
   public static final int DISPLAY_HEIGHT = 768;
}

Zmienne cieniowanie

„Jak powiedziałem wcześniej, nie można utworzyć wielu zmiennych lokalnych o tych samych nazwach w jednej metodzie. W różnych metodach jest to możliwe”.

"Wiem to!"

„Ale prawdopodobnie nie wiesz, że zmienne w klasie i zmienne lokalne w metodzie mogą mieć tę samą nazwę.

Przykład:

Kod Zmienna widoczność
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     sum = sum + data;
     int sum = data * 2;
     count++;
   }
}

count, sum
count, sum
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

„W addmetodzie zadeklarowaliśmy zmienną lokalną o nazwie sum. Do końca metody zasłania ona (lub maskuje ) sumzmienną instancji”.

„Hmm… powiedziałbym, że w pewnym sensie jest to oczekiwane zachowanie”.

„Ale to nie koniec historii. Okazuje się, że jeśli zmienna instancji jest zacieniona przez zmienną lokalną, nadal istnieje sposób na odwołanie się do zmiennej instancji w ramach metody. Robimy to, wpisując słowo kluczowe przed jego thisnazwą :

this.name

„Oto przykład pomyślnego rozwiązania konfliktu nazw:

Kod Zmienna widoczność
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     this.sum = this.sum + data;
     count++;
   }
}

this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum, data
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum

Zmienne counti sumsą dostępne wszędzie ze thissłowem kluczowym lub bez niego. W wierszach, w których sumzmienna lokalna przesłania zmienną suminstancji, sumdostęp do zmiennej instancji można uzyskać tylko za pomocą thissłowa kluczowego.

- Oczywiście, będę musiał to przećwiczyć.

— Poradzisz sobie.

„Co się stanie, jeśli statyczna zmienna klasy jest przesłonięta, a nie tylko (niestatyczna) zmienna instancji? Nie możesz uzyskać do niej dostępu przez this?”

„Zgadza się. Słowo kluczowe this nie zadziała. Musisz odnieść się do niego poprzez nazwę klasy:

ClassName.name

Przykład:

Kod Zmienna widoczność
public class Solution
{
   public static int count = 0;
   public static int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     Solution.sum = Solution.sum + data;
     count++;
   }
}

Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum, data
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum

„Uwaga: możesz uzyskać dostęp do zmiennych statycznych counti sumwszędzie, używając nazwy klasy Solutionjako prefiksu lub bez niej. W tych wierszach, w których sumzmienna lokalna zasłania sumzmienną instancji, dostęp do sumzmiennej klasy jest możliwy tylko wtedy, gdy jest używany Solutionjako prefiks.

Zmienne wewnątrz forpętli

„I jeszcze jeden mały, ale interesujący fakt. Jest też miejsce, w którym zmienna jest deklarowana w specjalny sposób — mówię o wewnątrz pętli for . Zazwyczaj forpętla ma counterzmienną w nawiasach. A jaka będzie widoczność tej zmiennej? W końcu nie znajduje się w ciele pętli. Czy to cała metoda? Albo nie?"

„Coś już o tym słyszałem. Jak rozumiem, zmienna zadeklarowana w nagłówku pętli forjest widoczna tylko w ciele pętli iw nagłówku pętlifor ”.

„Dobra robota, Amigo. Ale mimo to spójrz na przykład wzmacniający ten materiał:

Kod Zmienna widoczność
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a

„Więc mówisz, że w moim kodzie mógłbym napisać kilka pętli jedna po drugiej ze zmienną licznika o tej samej nazwie i nie byłoby problemów?”

„Nie byłoby problemów. Proszę spojrzeć:

Kod Zmienna widoczność
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   for (int i = 0; i < 10; i--)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a, i
a, i
a, i
a
a
a