1. Słowo kluczowe var
Kiedy dopiero zaczynamy pisać kod w Javie, spotyka nas ścisły system typów: każdą zmienną trzeba zadeklarować jawnie — wskazać jej typ. To korzystne dla niezawodności, ale czasem zapisy stają się rozwlekłe i przeładowują kod. Aby ułatwić życie, do Javy dodano wygodne narzędzie — wnioskowanie typu (var).
var pozwala pisać krótszy i czystszy kod, nie rezygnując z bezpieczeństwa typów: wpisujesz wartość, a kompilator sam wnioskuje typ.
Przykład
var age = 23; // kompilator określi typ liczby 23 i wstawi int age
var name = "Anna"; // kompilator określi typ "Anna" i wstawi String name
var price = 99.99; // kompilator określi typ 99.99 i wstawi double price
Dlaczego pojawiło się var?
- Czytelność: nie trzeba ręcznie pisać długich typów (takich jak HashMap<String, List<Integer>>).
- Elastyczność: łatwiej zmieniać typy w przyszłości: poprawisz po prawej — po lewej var już się dostosuje.
- Nowoczesny styl: praktycznie wszystkie współczesne projekty Java używają var tam, gdzie typ łatwo odczytać z inicjalizacji.
Kiedy można (i warto) używać var
- Kiedy z prawej strony jednoznacznie widać, jaki jest typ zmiennej.
- Kiedy typ jest oczywisty (var price = 100; — jasne, że to int).
- Kiedy typ jest zbyt długi lub złożony (np. HashMap<Integer, List<Calendar>>).
Przykład z tablicą
var numbers = new int[] { 1, 2, 3, 4 };
Przykład z metodą
var input = console.nextLine(); // input — to String (metoda zwraca String)
Kiedy lepiej NIE używać var
Jeśli typ nie jest oczywisty z prawej strony, kod może stać się mniej zrozumiały. Jeśli za miesiąc sam nie zrozumiesz, jaki to typ, lepiej podać go jawnie.
var mystery = DoSomethingVeryComplicated(); // KIM JESTEŚ, mystery???
Tutaj lepiej podać typ jawnie:
String result = DoSomethingVeryComplicated();
Złota zasada: używaj var tylko tam, gdzie nie pogarsza czytelności!
var — tylko dla zmiennych lokalnych
Słowo kluczowe var działa tylko dla zmiennych lokalnych — wewnątrz metod. Nie można używać var dla:
- parametrów metody;
- pól klasy;
- stałych.
Jak działa var „pod maską”
- Kompilator Javy podczas kompilacji podstawia właściwy typ.
- Po kompilacji nie pozostaje żadne var.
- Brak utraty wydajności: to wygoda tylko dla programisty.
var year = 2025; // na etapie kompilacji staje się: int year = 2025;
Typowe błędy przy użyciu var
Niezainicjalizowana zmienna:
var a; // BŁĄD: kompilator nie ma z czego wywnioskować typu!
Niejednoznaczna inicjalizacja:
var list = null; // BŁĄD: typ null nie jest określony!
Ponowne użycie zmiennej z różnymi typami:
var value = 5; // value — int
value = "Pięć"; // BŁĄD: value to już int!
Porównanie: typy jawne i var
| Scenariusz | Typ jawny | var |
|---|---|---|
| Typ jednoznaczny | |
|
| Metoda zwraca złożony typ | |
|
| Tablica | |
|
2. Słowo kluczowe final: deklarowanie stałych
Stała to zmienna, której wartości nie można zmienić po inicjalizacji. Stałe czynią kod niezawodnym, czytelnym i chronią przed przypadkowymi zmianami ważnych liczb i łańcuchów.
- Liczba Pi (PI = 3.14159…)
- Maksymalna liczba użytkowników (MAX_USERS = 1000)
- Nazwa firmy (COMPANY_NAME = "CodeGym")
W Javie do deklaracji stałej używa się modyfikatora final. Mówi on kompilatorowi: „po pierwszym przypisaniu — dalej nie wolno zmieniać!”
final Typ NAZWA_STAŁEJ = wartość;
Składnia
final int DAYS_IN_WEEK = 7;
final double PI = 3.1415926535;
final String GREETING = "Cześć, Java!";
Ważne kwestie:
- Zmienna z final musi być zainicjalizowana (od razu lub w konstruktorze — jeśli to pole klasy).
- Próba zmiany wartości spowoduje błąd kompilacji.
Przykład: nie można zmienić final zmiennej
final int MAX_USERS = 100;
MAX_USERS = 200; // Błąd: nie można przypisać nowej wartości do zmiennej final
Komentarz: jeśli odkomentujesz przypisanie — projekt się nie zbuduje.
3. static final: stałe na poziomie klasy
W Javie często potrzebne są stałe niezależne od konkretnego obiektu — „wspólne” dla całej klasy. Do tego używa się połączenia static + final.
Dlaczego static final?
- static — zmienna należy do klasy (jedna dla wszystkich).
- final — nie można zmienić wartości.
Składnia
public static final double PI = 3.1415926535;
public static final int MAX_USERS = 1000;
public static final String COMPANY_NAME = "CodeGym";
Gdzie deklarować? Zwykle na początku klasy (przed metodami).
Przykład użycia w klasie
public class MathUtils
{
public static final double PI = 3.1415926535;
public static double circleLength(double radius)
{
return 2 * PI * radius;
}
}
Wywołanie:
double len = MathUtils.circleLength(5);
System.out.println(len); // 31.4159...
Zwróć uwagę: do stałej odwołujemy się przez nazwę klasy: MathUtils.PI.
4. Różnica między samym final a static final
final — wartości pola nie można zmienić po inicjalizacji, ale każdy obiekt ma własną wartość.
static final — jedna stała na całą klasę, niezależna od obiektów.
Przykład: różnica w praktyce
public class User
{
public final String name; // Każdy User ma własne imię (final)
public static final String COMPANY = "CodeGym"; // Jedna firma dla wszystkich (static final)
public User(String name)
{
this.name = name;
}
}
User u1 = new User("Alice");
User u2 = new User("Bob");
System.out.println(u1.name); // Alice
System.out.println(u2.name); // Bob
System.out.println(User.COMPANY); // CodeGym
Wniosek: name — indywidualne niezmienialne pole, COMPANY — wspólna stała.
Konwencje nazewnicze dla stałych
Stałe nazywa się WIELKIMI_LITERAMI_Z_PODKREŚLENIEM.
public static final int MAX_USERS = 1000;
public static final double GRAVITY = 9.81;
public static final String DEFAULT_GREETING = "Hello, world!";
Wskazówka: widzisz taką nazwę — nie próbuj zmieniać wartości w kodzie: kompilator na to nie pozwoli.
5. Praktyka: deklarowanie i używanie stałych
Przykład: klasa ze stałymi
public class CircleCalculator
{
public static final double PI = 3.1415926535;
public static double getLength(double radius)
{
return 2 * PI * radius;
}
public static double getArea(double radius)
{
return PI * radius * radius;
}
}
Użycie:
public class Main
{
public static void main(String[] args)
{
double r = 5.0;
System.out.println("Długość okręgu: " + CircleCalculator.getLength(r));
System.out.println("Pole koła: " + CircleCalculator.getArea(r));
}
}
Wynik:
Długość okręgu: 31.415926535
Pole koła: 78.5398163375
Próba zmiany stałej
CircleCalculator.PI = 3.14; // Błąd kompilacji: cannot assign a value to final variable PI
6. Szczegóły i niuanse
Stałe dla obiektów
Można oznaczać final referencje do obiektów, ale to nie czyni obiektu niezmiennym! To jedynie zakazuje przypisania do zmiennej innej referencji.
final StringBuilder sb = new StringBuilder("Hello");
sb = new StringBuilder("World"); // Błąd: nie można przypisać nowego obiektu
sb.append(", Java!"); // Dozwolone — zmienia się stan obiektu
System.out.println(sb); // Hello, Java!
Wniosek: final chroni referencję, a nie obiekt. Dla prawdziwej niezmienności używaj klas niemutowalnych (np. String, List.of() itd.).
Użycie stałych zamiast „magicznych liczb”
Zły styl:
double area = 3.1415 * r * r; // Co to 3.1415? Dlaczego akurat ta liczba?
Dobry styl:
double area = PI * r * r; // Od razu wiadomo, że używana jest liczba Pi
7. Typowe błędy przy pracy ze stałymi i var
Błąd nr 1: próba zmiany wartości final zmiennej. Jeśli zmienna została zadeklarowana z final, ponowne przypisanie spowoduje błąd kompilacji.
Błąd nr 2: próba zadeklarowania stałej przez var. Dla stałych zawsze używaj typu jawnego wraz z final lub static final. var — tylko dla zmiennych lokalnych.
Błąd nr 3: nieprawidłowe nazewnictwo stałych. Stałe powinny mieć WIELKIE_LITERY_Z_PODKREŚLENIEM. Zapis w rodzaju final int maxUsers = 100; pogarsza czytelność.
Błąd nr 4: zapomniany zakres widoczności. Stała zadeklarowana wewnątrz metody jest widoczna tylko w niej. Aby używać w całej klasie, deklaruj na poziomie klasy jako static final.
Błąd nr 5: myślenie, że final czyni obiekt niezmiennym. final unieruchamia referencję, a nie stan obiektu — to różne rzeczy.
GO TO FULL VERSION