Lepsza nauka

Błędy kompilacji w Javie: 10 najczęstszych wyjaśnionych po polsku

Opublikowano 22 października 20265 min czytania

Klikasz „Uruchom”, a zamiast wyniku widzisz czerwony tekst po angielsku. To zdarza się każdemu, także zawodowym programistom, codziennie. Dobra wiadomość: prawie wszystkie błędy na początku nauki to kilka tych samych komunikatów. Tutaj poznasz dziesięć najczęstszych, każdy z małym zepsutym przykładem i rozwiązaniem.

Jak czytać komunikat błędu w Javie

Kompilator javac tłumaczy twój kod, zanim program się uruchomi. Jeśli znajdzie błąd, wygląda to tak:

Main.java:3: error: ';' expected
        int age = 17
                    ^
1 error

W tym komunikacie są trzy informacje:

  1. Plik i wiersz: Main.java:3 oznacza wiersz 3.
  2. Treść błędu: wszystko po error: mówi, co przeszkadza Javie.
  3. Daszek ^: wskazuje miejsce, w którym Java się poddała. Właściwy błąd jest często dokładnie tam albo tuż przed nim.

Przy kilku komunikatach zasada jest prosta: zawsze poprawiaj pierwszy i kompiluj od nowa. Jeden błąd potrafi wywołać wiele kolejnych, które potem znikają same.

Komunikaty javac są po angielsku, dlatego poniżej zostawiamy je w oryginale. Wyjaśnienie dostajesz po polsku.

Błędy składni: Java nie rozumie budowy zdania

1. ';' expected

Na końcu instrukcji brakuje średnika. Java zauważa to dopiero na końcu wiersza, dlatego daszek stoi za 17.

int age = 17System.out.println(age);

Rozwiązanie: int age = 17;. Jeśli komunikat wskazuje wiersz, który wygląda poprawnie, sprawdź wiersz wyżej. Podobny komunikat to ')' or ',' expected: wtedy brakuje nawiasu zamykającego, często tuż przed średnikiem.

2. reached end of file while parsing

Java doszła do końca pliku, a jakiś blok jest wciąż otwarty. Brakuje zamykającego nawiasu klamrowego.

public class Main {    public static void main(String[] args) {        System.out.println("Cześć");    }

Rozwiązanie: dopisz brakującą } na końcu. Żeby to się nie powtarzało, do każdej { od razu pisz pasującą } i porządnie rób wcięcia. Funkcja formatowania w edytorze szybko pokaże, gdzie blok się nie zgadza.

Nazwy i typy

3. cannot find symbol

Najczęstszy komunikat w ogóle. Java nie zna w tym miejscu jakiejś nazwy. Której, widzisz pod symbol:.

Main.java:4: error: cannot find symbol
        System.out.println(Count);
                           ^
  symbol:   variable Count
  location: class Main

Typowe przyczyny:

  • Literówka albo wielkość liter: Count to nie count, string to nie String.
  • Zmienna nie została zadeklarowana: używasz jej, zanim zadeklarujesz ją z typem.
  • Zły blok: zmienna z pętli albo z if istnieje tylko w środku tego bloku.
  • Brak importu: Scanner potrzebuje import java.util.Scanner;, tak jak w artykule o wejściu i wyjściu w Javie.

4. incompatible types: String cannot be converted to int

Wartość nie pasuje do typu zmiennej. Tutaj tekst ma trafić do liczby.

int points = "12";

Rozwiązanie: albo int points = 12; bez cudzysłowu, albo świadoma konwersja: int points = Integer.parseInt("12");. Komunikat zawsze podaje oba typy: najpierw ten, który dostała Java, potem ten, którego oczekuje.

5. incompatible types: possible lossy conversion from double to int

Wartość double ma trafić do zmiennej int. Część ułamkowa by przepadła, dlatego Java odmawia.

double average = 2.7;int rounded = average;

Rozwiązanie: użyj pasującego typu (double rounded = average;) albo rzutuj jawnie: int rounded = (int) average;. Uwaga: rzutowanie obcina i daje 2, a nie 3. Do zaokrąglania służy Math.round.

6. bad operand types for binary operator '>'

Operator nie pasuje do typów. Klasyka: porównywanie Stringów przez > albo ==.

Main.java:7: error: bad operand types for binary operator '>'
        if (name > "Ola") { }
                 ^
  first type:  String
  second type: String

Rozwiązanie: Stringi porównujesz metodami. name.equals("Ola") sprawdza równość, name.compareTo("Ola") > 0 kolejność alfabetyczną. Więcej w artykule o Stringach w Javie.

Metody, zmienne i klasy

7. missing return statement

Metoda obiecuje zwrócić wartość, ale nie każda ścieżka kończy się instrukcją return.

static int max(int a, int b) {    if (a > b) {        return a;    } else if (b >= a) {        return b;    }}

Dla ciebie jest jasne, że jeden z przypadków zawsze zajdzie. Java nie sprawdza jednak treści warunków. Rozwiązanie: zamień else if na zwykłe else albo dodaj return na końcu. Jak działają wartości zwracane, wyjaśnia artykuł o metodach i rekurencji.

8. variable sum might not have been initialized

Zmienna jest odczytywana, zanim na pewno dostała wartość. Tutaj sum dostaje wartość tylko w if.

int sum;if (x > 0) {    sum = 5;}System.out.println(sum);

Rozwiązanie: nadaj zmiennej wartość początkową od razu przy deklaracji, czyli int sum = 0;.

9. non-static method greet() cannot be referenced from a static context

main jest static. Należy do klasy, a nie do obiektu, więc nie może bezpośrednio używać metod ani zmiennych bez static. Dla zmiennych komunikat brzmi non-static variable count cannot be referenced from a static context.

public class Main {    void greet() {        System.out.println("Hej");    }
    public static void main(String[] args) {        greet();    }}

Rozwiązanie: napisz static void greet() albo utwórz obiekt: new Main().greet();. Na czym dokładnie polega różnica, dowiesz się z artykułu o klasach i obiektach.

10. class Hello is public, should be declared in a file named Hello.java

Klasa public musi nazywać się dokładnie tak jak jej plik. Plik nazywa się Main.java, a klasa Hello.

public class Hello {    public static void main(String[] args) {        System.out.println("Hej");    }}

Rozwiązanie: zmień nazwę klasy na Main albo nazwę pliku na Hello.java. Zdarza się to często, gdy kopiujesz kod z filmu albo z czatu.

A wyjątki w czasie działania?

Niektórych błędów nie zgłasza kompilator, tylko działający program. Wtedy widzisz wyjątek z numerem wiersza:

Wyjście
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at Main.main(Main.java:5)

Tablica ma trzy elementy o indeksach od 0 do 2, a pętla chciała odczytać indeks 3. Prawie zawsze w warunku stoi <= zamiast <. Zajrzyj do artykułu o tablicach w Javie. Drugi częsty wyjątek to NullPointerException, na przykład Cannot invoke "String.length()" because "name" is null: zmienna nie wskazuje na żaden obiekt. Jak świadomie obsługiwać takie sytuacje, opisuje artykuł o wyjątkach i enumach.

Szybciej rozumiesz błędy z Jario

Jeśli instalujesz Javę u siebie, często pojawia się jeszcze jeden błąd przed wszystkimi innymi. Ma osobny wpis: „javac” nie jest rozpoznawany. W Jario ten problem znika, bo piszesz kod w przeglądarce, a uruchamiamy go na naszym serwerze.

Przy błędach kompilacji Jario pomaga ci w dwóch miejscach. Przy komunikacie wskazówka „Co to znaczy?” wyjaśnia po polsku najczęstsze błędy kompilatora, czyli właśnie te z tego wpisu. Jeśli to nie wystarczy, możesz zapytać tutora AI przyciskiem „Wyjaśnij błąd”. Tutor zna zadanie i twój kod, więc tłumaczy błąd w twoim miejscu, ale nie pisze za ciebie rozwiązania. Do tego edytor zaznacza błędy bezpośrednio w kodzie, a nieskończona pętla niczego nie zawiesza, tylko zostaje zatrzymana z komunikatem „Przekroczony limit czasu. Prawdopodobnie nieskończona pętla.”

Jeśli wolisz wklejać błędy do czatu, we wpisie Nauka Javy z ChatGPT znajdziesz zasady, dzięki którym i tak czegoś się nauczysz. A jeśli na kolokwium musisz poradzić sobie bez kompilatora, pomoże ci wpis Kolokwium z Javy na kartce. Od dziś czytaj każdy komunikat świadomie: pierwszy błąd, wiersz, daszek. Po kilku dniach rozpoznasz te dziesięć klasyków na pierwszy rzut oka.

Powiązane artykuły do nauki

Więcej wpisów