Kurs Java #7 Instrukcje warunkowe

Java

Loading

Wprowadzenie

Instrukcje warunkowe to jeden z fundamentów każdego języka programowania. Pozwalają one sterować przepływem programu w zależności od spełnienia określonych logicznych warunków (boolean). W tym artykule poznasz wszystkie podstawowe konstrukcje warunkowe w języku Java.

Instrukcja if

Pozwala wykonać fragment kodu tylko wtedy, gdy podany warunek logiczny (boolean) jest spełniony. Jest to najprostsza forma podejmowania decyzji w programie. 

int liczba = 10;
if (liczba > 0) {
    System.out.println("Liczba jest dodatnia.");
}

Warunek wewnątrz if musi być typu boolean. W przeciwnym razie kompilator zgłosi błąd:

Instrukcja if-else

Kiedy chcesz wykonać jedną z dwóch możliwych akcji w zależności od warunku — użyj konstrukcji if-else.

int liczba = -5;
if (liczba > 0) {
    System.out.println("Liczba jest dodatnia.");
} else {
    System.out.println("Liczba nie jest dodatnia.");
}

Instrukcja if, else-if, else

Czasami potrzebujemy sprawdzić więcej niż dwa przypadki. Wtedy przydaje się łańcuch warunków if, else-if, else, który umożliwia sprawdzanie kilku warunków po kolei.

int liczba = 0;
if (liczba > 0) {
    System.out.println("Liczba jest dodatnia.");
} else if (liczba < 0) {
    System.out.println("Liczba jest ujemna.");
} else {
    System.out.println("Liczba jest równa zero.");
}

Zagnieżdżone instrukcje warunkowe

Możemy umieszczać jedne instrukcje warunkowe wewnątrz innych — na przykład wtedy, gdy zależność między warunkami jest bardziej złożona. Warto jednak dbać o przejrzystość kodu.

int wiek = 25;
boolean maPrawoJazdy = true;
if (wiek >= 18) {
    if (maPrawoJazdy) {
        System.out.println("Możesz prowadzić samochód.");
    }
}

Zagnieżdżone warunki są dozwolone, ale mogą pogarszać czytelność. Warto rozważyć uproszczenie:

if (wiek >= 18 && maPrawoJazdy) {
    System.out.println("Możesz prowadzić samochód.");
}

Operator warunkowy (trójargumentowy) ? :

Ten operator był już opisywany w lekcji: Kurs Java #5 Operatory matematyczne i logiczne, ale dla przypomnienia opiszę go krótko jeszcze raz.  Operator warunkowy to uproszczona wersja instrukcji if-else, używana zazwyczaj do przypisywania wartości w zależności od warunku. Skraca kod i poprawia czytelność w prostych przypadkach.

int wiek = 18;
String status = (wiek >= 18) ? "Pełnoletni" : "Niepełnoletni";
System.out.println(status);

Instrukcja switch

Kiedy potrzebujesz sprawdzić jedną zmienną względem wielu wartości — np. dni tygodnia, role użytkownika — zamiast wielu if-else warto zastosować switch.

String rola = "admin";
switch (rola) {
    case "admin":
        System.out.println("Dostęp administratora.");
        break;
    case "user":
        System.out.println("Dostęp użytkownika.");
        break;
    default:
        System.out.println("Brak dostępu.");
}

Nowoczesna składnia switch

Od Javy 14 można korzystać z nowej, bardziej przejrzystej składni switch, która przypomina wyrażenia przypisujące wartość. Dzięki niej można uniknąć break i zyskać czytelniejszy kod.

int dzien = 3;
String nazwaDnia = switch (dzien) {
    case 1 -> "Poniedziałek";
    case 2 -> "Wtorek";
    case 3 -> "Środa";
    default -> "Nieznany dzień";
};
System.out.println(nazwaDnia);

Typowe błędy w instrukcjach warunkowych

Instrukcje warunkowe (if, else if, else, switch) to podstawowy sposób podejmowania decyzji w programie. Jednak nawet proste konstrukcje mogą prowadzić do błędów, jeśli nie są używane świadomie. Poniżej znajdziesz zestawienie najczęstszych pomyłek oraz sposoby ich unikania.

1. Brak nawiasów klamrowych {}

Jeśli po if, else if lub else znajduje się tylko jedna linijka kodu, nawiasy {} nie są obowiązkowe — ale ich brak może prowadzić do błędów, zwłaszcza przy rozbudowie kodu.

Niepoprawny przykład:

2. Użycie == zamiast .equals() do porównywania Stringów

W Javie operator == porównuje, czy dwa obiekty to ten sam obiekt w pamięci, a nie czy mają taką samą wartość. W przypadku typów referencyjnych (jak String) może to prowadzić do nieprzewidywalnych wyników.

Niepoprawny przykład:

Na powyższym przykładzie widać, że kod zadziałał, ale jest to zależne od implementacji i kontekstu. Dlatego wiele IDE (np. IntelliJ, Eclipse, NetBeans) ostrzeże Cię, że taki kod jest potencjalnie błędny, co jest słuszne.

Poprawny przykład:

3. Brak pokrycia wszystkich przypadków w if-else lub switch

Pominięcie else lub default może spowodować, że niektóre przypadki nie zostaną obsłużone.

Niepoprawny przykład:

4. Niewłaściwe użycie operatora przypisania =

Częsty błąd to przypadkowe użycie zamiast == w warunku, co prowadzi do przypisania, a nie porównania.

Niepoprawny przykład:

Poprawny przykład:

Poprawny i najlepszy przykład:

5. Zbyt złożone warunki logiczne bez nawiasów

Brak nawiasów w złożonych wyrażeniach && i || może prowadzić do nieoczekiwanych rezultatów z powodu kolejności wykonywania.

Niepoprawny przykład:

Poprawny przykład:

6. Nadmiarowe warunki

Czasem programiści niepotrzebnie komplikują warunki logiczne.

Niepoprawny przykład:

if (aktywny == true) {
     // ...
}

Poprawny przykład:

if (aktywny) {
    // ...
}

7. Brak break w klasycznym switch

Brak break powoduje tzw. przepływ, czyli wykonanie kolejnych kodów bez kontroli. 

Poprawny przykład:

switch (opcja) {
    case 1:
        System.out.println("Opcja 1");
        break;
    case 2:
        System.out.println("Opcja 2");
        break;
}

8. Nieużycie default w switch

Brak default w switch może sprawić, że przypadki nieobsłużone pozostaną niezauważone. Default dodawaj zawsze, nawet jeśli tylko służy do logowania.

Poprawny przykład:

default:
    System.out.println("Nieznana opcja");

Podsumowanie

Instrukcje warunkowe to fundament każdej logiki biznesowej w Javie. Choć składniowo są proste, to właśnie przez tę pozorną prostotę bardzo łatwo o pomyłki. W tym artykule omówiliśmy kilka najczęstszych błędów – praktyka, czytelność kodu i dbałość o detale są kluczem do pisania solidnych instrukcji warunkowych.

O autorze

Adam Mingielewicz

Tester oprogramowania z pasją do jakości i technologii. Łączy doświadczenie w testach manualnych i automatycznych, koncentrując się przede wszystkim na aplikacjach webowych oraz usługach SOAP i REST. Testowanie to dla niego nie tylko szukanie błędów, ale przede wszystkim kwestionowanie przyjętych założeń i usprawnianie tego, co nie działa – również w samym procesie testowym. Lubi zmieniać, angażować się i aktywnie budować proces testowy, tak by miał sens, a nie tylko formę. Prywatnie fan rocka, biwakowania, podróży.