PrzedsprzedażAkademia AI w testach i jakości oprogramowania: 1 350 zł zamiast 1 750 zł netto do 30 listopada

Startuje przedsprzedaż Akademii AI w testach i jakości oprogramowania: 5 tygodni z Tomaszem Stelmachem, start 11 stycznia 2027. Wyjątkowa cena 1 350 zł netto zamiast 1 750 zł tylko do 30 listopada.

zostało 25 dniZobaczcie program i zapiszcie się
Komentarze w kodzie Java: jednolinijkowe, blokowe, Javadoc i Markdown od JDK 23
Czas czytania: 13 minut

Komentarze w kodzie to fragmenty tekstu, które kompilator Javy całkowicie pomija, a które czyta człowiek: Wy za pół roku, osoba z Waszego zespołu albo narzędzie javadoc, które robi z nich dokumentację HTML. Java ma trzy klasyczne rodzaje komentarzy: jednolinijkowe //, blokowe /* */ i dokumentujące /** */, a od JDK 23 doszły komentarze dokumentujące w Markdownie, zaczynane od ///. Ta lekcja pokazuje wszystkie cztery na jednym działającym przykładzie, trzy błędy kompilatora, które komentarz potrafi wywołać, i zasady komentowania testów automatycznych, bo w testach komentarz częściej szkodzi, niż pomaga.

To piąta lekcja kursu Javy dla testerów na blogu Quality Island. Wcześniej napisaliście pierwszy program w Javie, a po tej lekcji przejdziecie do typów danych w Javie. Film poniżej pokazuje temat na ekranie IntelliJ IDEA, tekst pod nim rozwija go o rzeczy, których w filmie nie ma: Markdown w Javadoc, komunikaty kompilatora i komentarze w testach JUnit.

Jakie rodzaje komentarzy w kodzie ma Java?

Java rozróżnia komentarze po pierwszych znakach. Kompilator javac traktuje każdy z nich jak białą spację, więc żaden komentarz nie zmienia działania programu ani jego szybkości. Różnią się tym, kto je czyta: komentarze // i /* */ są wyłącznie dla ludzi czytających kod, a komentarze dokumentujące czyta dodatkowo narzędzie javadoc i środowisko programistyczne, które pokazuje je w podpowiedziach po najechaniu na nazwę metody.

Rodzaj Składnia Od wersji Kto czyta Kiedy używać
Jednolinijkowy // tekst Java 1.0 ludzie krótkie wyjaśnienie „dlaczego” przy linii kodu
Blokowy /* tekst */ Java 1.0 ludzie dłuższa notatka, np. decyzja projektowa z numerem zgłoszenia
Dokumentujący /** tekst */ Java 1.0 ludzie, javadoc, IDE opis klasy, pola i metody publicznej
Dokumentujący w Markdownie /// tekst JDK 23 (JEP 467) ludzie, javadoc 23+, IDE to samo co /** */, ale bez znaczników HTML

Wszystkie cztery rodzaje widać w jednej klasie poniżej. To prosty kalkulator rabatu ze sklepu testowego: liczy cenę w groszach, żeby uniknąć błędów zaokrągleń, o których więcej powiemy w następnej lekcji. Kod skompilowaliśmy i uruchomiliśmy 11.10.2026 na OpenJDK 25.0.2 z opcją --release 25, czyli tak, jak buduje go projekt Maven z lekcji 3.

package pl.qi;

/**
 * Liczy cenę po rabacie dla koszyka w sklepie testowym.
 * <p>
 * Klasa jest celowo mała: służy jako przykład komentarzy dokumentujących.
 *
 * @author Quality Island
 * @since 1.0
 */
public class Rabat {

    /** Najwyższy rabat procentowy, jaki przyjmuje sklep. */
    public static final int MAKS_RABAT = 50;

    /**
     * Zwraca cenę po rabacie, zaokrągloną w dół do pełnych groszy.
     *
     * @param cenaWGroszach cena przed rabatem, w groszach, nie mniejsza niż 0
     * @param procent       rabat w procentach, od 0 do {@value #MAKS_RABAT}
     * @return cena po rabacie w groszach
     * @throws IllegalArgumentException gdy procent jest poza zakresem
     * @see <a href="https://qualityisland.pl/typy-danych-w-javie/">Typy danych w Javie</a>
     */
    public static long poRabacie(long cenaWGroszach, int procent) {
        if (procent < 0 || procent > MAKS_RABAT) {
            throw new IllegalArgumentException("Rabat poza zakresem: " + procent);
        }
        // Liczymy w groszach, bo double gubi grosze (szczegóły w lekcji o typach danych)
        return cenaWGroszach * (100 - procent) / 100;
    }

    /*
     * Wersja z zaokrągleniem do góry była w sprincie 14,
     * ale dział finansów wybrał zaokrąglenie w dół (zgłoszenie SKLEP-482).
     */

    /// Zwraca **true**, gdy rabat da się zastosować.
    ///
    /// Komentarz w składni Markdown (JEP 467, od JDK 23):
    /// - `procent` musi być w zakresie od 0 do [#MAKS_RABAT]
    /// - metoda nie rzuca wyjątków
    ///
    /// @param procent rabat w procentach
    /// @return `true` dla poprawnego rabatu
    public static boolean czyPoprawny(int procent) {
        return procent >= 0 && procent <= MAKS_RABAT;
    }

    public static void main(String[] args) {
        System.out.println(poRabacie(19_999, 15)); // 199,99 zł minus 15%
        System.out.println(czyPoprawny(60));
    }
}
$ javac -d out src/pl/qi/Rabat.java
$ java -cp out pl.qi.Rabat
16999
false

Jak działa komentarz jednolinijkowy i blokowy?

Komentarz jednolinijkowy zaczyna się od // i kończy razem z linią. Może stać w osobnej linii albo na końcu instrukcji, jak w przykładzie z rabatem. Komentarz blokowy zaczyna się od /*, kończy na */ i może obejmować dowolnie wiele linii. Gwiazdki na początku kolejnych linii są tylko konwencją, kompilator ich nie wymaga.

Według specyfikacji języka Java (JLS, rozdział 3.7, wydanie dla Java SE 25 z 2025 roku) komentarze się nie zagnieżdżają, a znaki /* i */ nie mają żadnego znaczenia wewnątrz komentarza zaczętego od //. Z tej jednej reguły wynikają dwa błędy opisane niżej w sekcji o kompilatorze. W IntelliJ IDEA nie musicie wpisywać znaków ręcznie: skrót Ctrl+/ (na macOS Cmd+/) komentuje lub odkomentowuje zaznaczone linie komentarzem jednolinijkowym, a Ctrl+Shift+/ (Cmd+Option+/) otacza zaznaczenie komentarzem blokowym. Środowisko poznaliście w lekcji IntelliJ IDEA: pierwszy projekt.

Najważniejsza zasada nie dotyczy składni, tylko treści. Dobry komentarz mówi, dlaczego kod wygląda tak, a nie inaczej; to, co kod robi, powinno wynikać z nazw zmiennych i metod. Komentarz // zwiększ licznik o 1 nad linią licznik++ nie wnosi nic. Komentarz // zaokrąglamy w dół, bo tak liczy system księgowy (SKLEP-482) ratuje kolejną osobę przed „naprawieniem” poprawnego kodu. Podobnie widzimy w projektach testowych: więcej kłopotu niż brakujące komentarze sprawiają nieaktualne, które mówią co innego niż kod. Jeśli Wasz zespół zmienia logikę, niech zmienia też komentarz w tym samym commicie, a przegląd kodu niech to sprawdza; to Wam oszczędzi najwięcej czasu.

Czym jest Javadoc i jakie tagi warto znać?

Javadoc to komentarz dokumentujący /** */ umieszczony bezpośrednio przed klasą, polem, konstruktorem albo metodą. Pierwsze zdanie trafia do podsumowania w wygenerowanej dokumentacji, reszta do opisu szczegółowego. Po opisie stoją tagi blokowe zaczynane od @, a w tekście można używać tagów wewnętrznych w nawiasach klamrowych. Specyfikacja komentarzy dokumentujących Oracle dla Java SE 25 (2025) opisuje 27 tagów; w codziennej pracy testera wystarczy kilka z tabeli.

Tag Co opisuje Przykład z klasy Rabat
@param parametr metody, po jednym tagu na parametr @param procent rabat w procentach
@return co zwraca metoda (pomijacie przy void) @return cena po rabacie w groszach
@throws wyjątek i warunek, w którym poleci @throws IllegalArgumentException gdy procent jest poza zakresem
@see odnośnik do innej klasy albo strony link do lekcji o typach danych
@since, @author wersja, od której element istnieje, i autor @since 1.0
@deprecated element do wycofania i czym go zastąpić razem z adnotacją @Deprecated
{@code ...} fragment kodu w tekście, bez interpretacji HTML {@code true}
{@link ...} klikalny odnośnik do innego elementu API {@link #czyPoprawny(int)}
{@value ...} wartość stałej wstawiona do opisu {@value #MAKS_RABAT} daje 50

Dokumentację HTML generuje narzędzie javadoc, które instaluje się razem z JDK. Wystarczy wskazać katalog ze źródłami i pakiet. Przy okazji javadoc sprawdza komentarze i ostrzega o brakach, co jest całkiem dobrym, darmowym przeglądem dokumentacji:

$ javadoc -d doc -sourcepath src pl.qi
src/pl/qi/Rabat.java:11: warning: use of default constructor, which does not provide a comment
public class Rabat {
       ^
src/pl/qi/Rabat.java:50: warning: no comment
    public static void main(String[] args) {
                       ^
2 warnings

Oba ostrzeżenia są uczciwe: klasa ma domyślny konstruktor bez opisu, a metoda main nie ma komentarza. W katalogu doc powstaje strona pl/qi/Rabat.html z opisem obu metod, tabelą parametrów i wartością stałej 50 wstawioną w miejsce tagu {@value}. W projekcie Maven to samo robi polecenie mvn javadoc:javadoc.

Jak pisać Javadoc w Markdownie od JDK 23?

Według JEP 467 „Markdown Documentation Comments”, dostarczonego w JDK 23, komentarz dokumentujący może składać się z linii zaczynanych od trzech ukośników ///, a jego treść jest pisana w Markdownie (CommonMark) zamiast w HTML. Pogrubienie piszecie jako **tekst**, kod jako `kod`, listy myślnikami na początku linii, a odnośnik do elementu API w nawiasach kwadratowych, np. [#MAKS_RABAT]. Tagi blokowe @param i @return działają jak wcześniej.

Metoda czyPoprawny w klasie Rabat ma właśnie taki komentarz. Po wygenerowaniu dokumentacji narzędziem javadoc z JDK 25 słowo **true** zamieniło się w znacznik <strong>, a nazwy w odwrotnych apostrofach w <code>, czyli Markdown został przetworzony tak, jak obiecuje JEP.

Wersje Javy, które spotkacie w projektach

17

LTS z września 2021, wsparcie Oracle Premier do września 2026

21

LTS z września 2023, wsparcie Premier do września 2028

23

wersja z JEP 467, komentarze dokumentujące w Markdownie

25

LTS z września 2025, wsparcie Premier do września 2030

Źródło: Oracle Java SE Support Roadmap, odczyt 10.10.2026; JEP 467, OpenJDK.

Jest jedna pułapka. Dla kompilatora /// to zwykły komentarz jednolinijkowy, więc klasa z takim komentarzem skompiluje się także na Javie 21 i starszej. Markdown zinterpretuje jednak dopiero javadoc w wersji 23 lub nowszej. Jeśli Wasz projekt budujecie na Javie 21, a dokumentację generujecie tym samym JDK, komentarze /// po prostu znikną z dokumentacji. W takim projekcie zostańcie przy /** */; po przejściu na Javę 25 możecie przechodzić na Markdown stopniowo, bo oba style mogą żyć w jednym pliku.

Jakie błędy kompilatora powodują komentarze w kodzie?

Komentarz wydaje się najbezpieczniejszym miejscem w pliku, a jednak potrafi zatrzymać kompilację. Wszystkie trzy błędy z tabeli wywołaliśmy celowo i przepisaliśmy komunikaty z javac 25 uruchomionego z angielskimi komunikatami, bo takie zobaczycie w większości pipeline’ów CI.

Kod Komunikat kompilatora Przyczyna i naprawa
/* zewnętrzny /* wewnętrzny */ dalej zewnętrzny */ error: ';' expected komentarze się nie zagnieżdżają: pierwszy */ kończy komentarz, a „dalej zewnętrzny */” kompilator czyta jak kod. Zakomentujcie blok komentarzami // (Ctrl+/)
/* TODO: dopisać walidację bez zamknięcia error: unclosed comment oraz error: reached end of file while parsing brak */, komentarz połknął resztę pliku razem z nawiasami klamrowymi
// raport w C:\users\tester\raporty error: illegal unicode escape sekwencja \u jest przetwarzana przed komentarzami, nawet w //. Piszcie ścieżki z ukośnikami / albo podwójnym \\

Trzeci błąd wydaje się absurdalny, dopóki nie zobaczycie, skąd się bierze. Według JLS (rozdział 3.3) kompilator zamienia sekwencje Unicode \uXXXX na znaki, zanim w ogóle zacznie szukać komentarzy. Ścieżka C:\users zawiera \u, po którym nie stoją cztery cyfry szesnastkowe, więc kompilator zgłasza błąd w linii, która „przecież jest komentarzem”.

Komentarz, który się wykonuje

Ta sama reguła ma ciemniejszą stronę. Sekwencja \u000d to znak powrotu karetki, czyli koniec linii. Jeśli stanie w komentarzu jednolinijkowym, reszta linii przestaje być komentarzem i wykonuje się jak zwykły kod. Program poniżej wypisał w naszym uruchomieniu Test wyłączony: false, choć jedyna linia zmieniająca zmienną wygląda na zakomentowaną. Dlatego w przeglądach kodu testów warto zwracać uwagę na \u w komentarzach: to rzadki przypadek, ale linia, która wygląda na wyłączoną, a działa, potrafi zmarnować cały dzień debugowania.

public class Unicode {
    public static void main(String[] args) {
        boolean wylaczony = true;
        // \u000d wylaczony = false;
        System.out.println("Test wyłączony: " + wylaczony);
    }
}
$ javac Unicode.java && java Unicode
Test wyłączony: false

Jak komentować testy automatyczne w Javie?

W testach automatycznych komentarz ma trudniejsze zadanie niż w kodzie produkcyjnym. Test jest jednocześnie kodem i specyfikacją zachowania systemu, więc jego treść powinna dać się przeczytać bez komentarzy. W naszej praktyce na przeglądach repozytoriów testów najczęściej poprawiamy dwa rodzaje komentarzy: zakomentowane całe testy i komentarze, które powtarzają nazwę metody. Zamiast nich JUnit daje dwa lepsze narzędzia: adnotację @DisplayName, która trafia do raportu, i @Disabled z powodem, który raport pokaże przy pominiętym teście.

package pl.qi;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class RabatTest {

    @Test
    @DisplayName("Rabat 15% od 199,99 zł daje 169,99 zł")
    void rabatZaokraglaWDol() {
        // Zaokrąglamy w dół, bo tak liczy system księgowy (SKLEP-482).
        // Bez tej informacji ktoś "naprawi" oczekiwane 16999 na 17000.
        long wynik = Rabat.poRabacie(19_999, 15);

        assertEquals(16_999, wynik);
    }

    @Test
    void rabatPowyzejLimituJestOdrzucany() {
        assertThrows(IllegalArgumentException.class, () -> Rabat.poRabacie(10_000, 51));
    }

    @Test
    @Disabled("SKLEP-517: rabat dla koszyka B2B jeszcze niewdrożony, włączyć po wydaniu 2.4")
    void rabatB2B() {
    }
}
RabatTest ✔
├─ Rabat 15% od 199,99 zł daje 169,99 zł ✔
├─ rabatB2B() ↷ SKLEP-517: rabat dla koszyka B2B jeszcze niewdrożony, włączyć po wydaniu 2.4
└─ rabatPowyzejLimituJestOdrzucany() ✔
3 tests found, 1 skipped, 2 successful, 0 failed

Test uruchomiliśmy w JUnit 6.1.3 (konsola JUnit Platform). Zwróćcie uwagę, że powód z @Disabled stoi w raporcie, a zakomentowanego testu raport w ogóle by nie pokazał: zniknąłby z liczby testów i nikt by o nim nie pamiętał. Komentarz w teście rabatZaokraglaWDol zostaje, bo wyjaśnia, dlaczego oczekiwany wynik to 16 999, a nie 17 000 groszy. Bez niego ktoś „naprawi” asercję przy pierwszym czerwonym przebiegu.

Komentujcie

powód nieoczywistej wartości oczekiwanej, numer zgłoszenia przy obejściu błędu, wybór lokatora w Selenium albo Playwright, np. // data-testid, bo klasy CSS zmieniają się przy każdym buildzie.

Zamieńcie na kod

opis kroku testu na nazwę metody pomocniczej, opis przypadku na @DisplayName, „tymczasowo wyłączone” na @Disabled("powód i zgłoszenie").

Usuńcie

zakomentowane testy i stare wersje asercji (historia jest w Git), komentarze powtarzające kod, TODO bez numeru zgłoszenia i daty.

Ta sama zasada działa w testach UI. Komentarz przy Thread.sleep(2000) typu „czekamy na stronę” jest sygnałem problemu, nie dokumentacją: zamiast go opisywać, zamieńcie go na jawne oczekiwanie z lekcji o explicit wait i implicit wait w Selenium WebDriver. Szerzej o nawykach, które psują zestawy testów, piszemy na portalu Strefa QA w tekście o najczęstszych antywzorcach w testowaniu oprogramowania. Komentarz „nie ruszać, działa” to najkrótsza forma dokumentacji i jednocześnie najdłuższa forma długu technicznego.

Ćwiczenie: jak udokumentować metodę z testu wydajności?

Zadanie: napiszcie metodę wLimicie(long czasMs, long limitMs), która sprawdza, czy zmierzony czas odpowiedzi API mieści się w limicie z wymagań niefunkcjonalnych. Udokumentujcie ją komentarzem Javadoc z tagami @param, @return i @throws, dodajcie jeden komentarz „dlaczego” w treści metody i wygenerujcie dokumentację poleceniem javadoc. Spróbujcie samodzielnie, zanim zajrzycie do rozwiązania.

Rozwiązanie

public class Cwiczenie {

    /**
     * Sprawdza, czy czas odpowiedzi API mieści się w limicie z wymagań.
     *
     * @param czasMs    zmierzony czas odpowiedzi w milisekundach
     * @param limitMs   limit z wymagań niefunkcjonalnych, w milisekundach
     * @return {@code true}, gdy czas nie przekracza limitu
     * @throws IllegalArgumentException gdy któraś wartość jest ujemna
     */
    public static boolean wLimicie(long czasMs, long limitMs) {
        if (czasMs < 0 || limitMs < 0) {
            throw new IllegalArgumentException("Czas nie może być ujemny");
        }
        // Równy limitowi przechodzi: tak mówi wymaganie (limit włącznie)
        return czasMs <= limitMs;
    }

    public static void main(String[] args) {
        System.out.println(wLimicie(800, 800));
    }
}

Program wypisuje true, bo czas równy limitowi przechodzi. Właśnie to opisuje komentarz w treści metody: przy wymaganiu „czas odpowiedzi do 800 ms” ktoś mógłby napisać < zamiast <= i test graniczny dla dokładnie 800 ms zacząłby padać. Javadoc dla tego pliku wygenerował się z czterema ostrzeżeniami o brakujących opisach klasy, konstruktora domyślnego i metody main; dopiszcie je, a ostrzeżeń nie będzie.

Poprzednia lekcjaLekcja 4: Java, pierwszy programNastępna lekcjaLekcja 6: Typy danych w Javie

Co dalej po lekcji o komentarzach?

Komentarze to najprostszy temat kursu, ale wracają w każdej kolejnej lekcji: od typów danych i operatorów matematycznych, przez funkcje, po klasy Page Object w testach Selenium. Jeśli wolicie przerobić podstawy Javy z trenerem, a nie z filmu, na szkoleniu Programowanie w języku Java dla testerów oprogramowania (2 dni, cena z karty szkolenia 2 212 zł netto, odczyt 10.10.2026) piszecie kod pod testy od pierwszego dnia. Dla osób, które zaczynają od zera, jest Wprowadzenie do programowania od podstaw w Javie, a kolejnym krokiem po podstawach jest kurs automatyzacji testów Selenium WebDriver.

Co zabrać z tego artykułu

01Java ma cztery rodzaje komentarzy: //, /* */, /** */ i od JDK 23 /// z Markdownem (JEP 467).

02Komentarze się nie zagnieżdżają, a \u w komentarzu jest przetwarzane przed nim: stąd błędy ';' expected i illegal unicode escape.

03Javadoc generuje dokumentację HTML i przy okazji ostrzega o brakujących opisach; najważniejsze tagi to @param, @return, @throws.

04Markdown w Javadoc wymaga narzędzia javadoc 23 lub nowszego; na Javie 21 zostańcie przy /** */.

05W testach zamiast komentarzy używajcie nazw metod, @DisplayName i @Disabled z powodem; komentarz zostawiajcie na „dlaczego”.

Źródło: JLS Java SE 25, rozdziały 3.3 i 3.7; JEP 467; uruchomienie kodu Quality Island na OpenJDK 25.0.2 i JUnit 6.1.3, 11.10.2026.

Chcecie pisać testy w Javie, które da się czytać bez komentarzy? Na szkoleniu Java dla testerów przerabiacie podstawy języka na przykładach z testów automatycznych.

Zobaczcie szkolenie Java dla testerów


Powiązane na blogu Quality Island

Pełna lista źródeł

Co o tym sądzisz?

Dodaj komentarz

Bądź na bieżąco
Strefa QA, portal z eksperckimi artykułami o jakości oprogramowania
Bądź na bieżąco
Specjalista ds. AI w organizacji
Specjalista ds. AI w organizacji: program przekwalifikowujący

4 400,00 zł

03.02.27, 14.04.27, 02.06.27
5 dni
Inżynier AI
Inżynier AI: program przekwalifikowujący dla specjalistów IT

6 900,00 zł

12.01.27, 16.03.27
8 tygodni
KURS ONLINE: PAQT Foundation, AI w pracy testera, przygotowanie do egzaminu

590,00 zł

Popularne artykuły
Język Gherkin: co to jest i jak go używać w testowaniu oprogramowania
Smoke test: co to jest, kiedy go uruchamiać i czym różni się od sanity testu
Jak zostać testerem oprogramowania: ścieżka krok po kroku bez dyplomu informatyka
Najnowsze artykuły
Audyt WCAG 2.2: przebieg, ceny w zł i szablon zapytania ofertowego
Tester manualny: co robi, ile zarabia w 2026 i checklista kompetencji na rozmowę
Art. 4 AI Act po Digital Omnibus: kompetencje w zakresie AI w zespole IT i QA, checklista i rejestr szkoleń
Popularne kategorie

Grupa marek jakości oprogramowania

Jakość oprogramowania w Polsce ma swój adres

Quality Island