Menu

Jak uruchomić program w Javie: kompilacja przez javac i uruchomienie przez java

Dwuetapowy cykl kompilacji i uruchomienia, na którym opiera się każdy program w Javie: zamiana kodu .java na bytecode przez javac, a potem uruchomienie pliku .class przez java.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Najpierw kompilacja, potem uruchomienie

Skoro masz już zainstalowane JDK, uruchamianie Javy to cykl dwuetapowy. W odróżnieniu od języka skryptowego, w którym wskazujesz interpreterowi plik i gotowe, Java najpierw kompiluje czytelny dla człowieka kod źródłowy do bytecode'u, a potem osobny krok uruchamia ten bytecode na JVM.

Te dwa kroki odpowiadają dwóm narzędziom wiersza poleceń dostarczanym z JDK:

  • javac: kompilator. Czyta Main.java i zapisuje Main.class (bytecode).
  • java: launcher. Uruchamia JVM i wykonuje bytecode z Main.class.

Każdy samodzielny przykład możesz uruchomić tutaj, na tej stronie: edytor poniżej wykonuje oba kroki za ciebie. Warto jednak rozumieć, co dzieje się na twoim własnym komputerze, bo tam żyją prawdziwe projekty.

Dwa polecenia na twoim komputerze

Załóżmy, że masz taki kod zapisany jako Main.java:

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

Otwórz terminal w folderze z tym plikiem i uruchom kompilator:

javac Main.java

Jeśli kod skompiluje się bez błędów, javac nic nie wypisuje i obok kodu źródłowego tworzy nowy plik Main.class. Ten plik .class to bytecode: nie jest czytelnym tekstem i nie jest związany z twoim systemem operacyjnym.

Teraz uruchom go poleceniem java:

java Main
Hello from the terminal

Tu zdarza się najczęstszy błąd początkujących: program uruchamiasz przez java, a nie javac, i podajesz nazwę klasy bez rozszerzenia. To java Main, nigdy java Main.class ani java Main.java.

Nazwa pliku musi pasować do klasy publicznej

Java wymusza regułę, która zaskakuje nowicjuszy: klasa public musi znajdować się w pliku o dokładnie tej samej nazwie z dopiskiem .java. public class Main musi być w Main.java. Pomyl wielkość liter, a javac odmówi kompilacji.

// This is in a file called Greeting.java
public class Greeting {   // ERROR: class Greeting should be in Greeting.java... wait, it is
    public static void main(String[] args) {
        System.out.println("Hi");
    }
}

Niezgodność, która naprawdę daje się we znaki, jest subtelniejsza: nazwanie pliku greeting.java (małymi literami), gdy klasa to Greeting, albo zapisanie Main.java z kodem public class Hello. Kompilator zgłasza wtedy coś w tym stylu:

Main.java:1: error: class Hello is public, should be declared in a file named Hello.java

Rozwiązanie jest zawsze takie samo: nazwa pliku i nazwa klasy publicznej muszą być identyczne, znak po znaku.

Skrót: uruchomienie pojedynczego pliku bezpośrednio

Od JDK 11 możesz pominąć jawny krok kompilacji dla pojedynczego pliku źródłowego. Polecenie java skompiluje go w pamięci i uruchomi za jednym razem, bez zapisywania pliku .class na dysk:

java Main.java

To idealne rozwiązanie do szybkich eksperymentów i małych skryptów. Zwróć uwagę na różnicę w tym, co podajesz:

  • java Main: uruchamia już skompilowany Main.class.
  • java Main.java: kompiluje i uruchamia plik źródłowy za jednym razem.

Tryb pojedynczego pliku działa tylko wtedy, gdy cały program mieści się w jednym pliku. Gdy tylko podzielisz kod na kilka klas w kilku plikach, wracasz do kompilowania najpierw przez javac. Podczas nauki podstaw tryb pojedynczego pliku skraca cykl pracy.

Przekazywanie argumentów do programu

Pamiętasz String[] args w main? To argumenty wiersza poleceń. Wszystko, co wpiszesz po nazwie klasy w poleceniu java, trafia do tej tablicy:

Na własnym komputerze przekazujesz argumenty w ten sposób:

java Main hello world
First argument: hello
Total arguments: 2

Edytor powyżej nie przyjmuje argumentów z terminala, więc uruchamia gałąź "bez argumentów", ale ten sam kod obsługuje oba przypadki. Tak programy w Javie czytają dane przekazane przy uruchomieniu, na długo zanim dojdziesz do plików czy danych od użytkownika.

Czytanie komunikatów kompilatora

Gdy javac odrzuca twój kod, podaje plik, linię i opis problemu. Umiejętność czytania tych komunikatów to połowa sukcesu, gdy utkniesz. Oto klasyk, czyli brakujący średnik:

public class Main {
    public static void main(String[] args) {
        System.out.println("Oops")   // no semicolon
    }
}
Main.java:3: error: ';' expected
        System.out.println("Oops")
                                  ^
1 error

Daszek (^) wskazuje miejsce, w którym kompilator czegoś oczekiwał. Main.java:3 to plik i numer linii. Nie zgaduj: przeczytaj linię, popraw tę jedną rzecz, którą wskazuje komunikat, i skompiluj ponownie. Błędy kompilacji oznaczają, że nic się jeszcze nie uruchomiło; błędy w czasie działania (wyglądają inaczej) oznaczają, że program wystartował, a potem się wysypał.

Program kontrolny

Uruchom go w edytorze albo zapisz jako Main.java i wykonaj javac Main.java, a potem java Main na własnym komputerze. Jeśli widzisz wszystkie trzy linie, twoje narzędzia działają od początku do końca:

Pojawiają się tu trzy rzeczy, które wkrótce poznasz dokładniej: zmienna typu int, łączenie napisów przez + i tablica z jej .length. Na razie wystarczy, że program się kompiluje i wypisuje wynik.

Dalej: składnia Javy

Uruchomiliśmy już kilka programów, ale interpunkcję omijaliśmy dotąd ogólnikami: nawiasy klamrowe, średniki, public static void main i powód, dla którego każda linia wygląda tak, a nie inaczej. Następna strona rozkłada składnię Javy na części, żeby struktura przestała wyglądać jak szablonowy kod i zaczęła mieć sens.

Najczęściej zadawane pytania

Jak uruchomić program w Javie?

Zapisz kod w pliku nazwanym tak jak klasa publiczna (np. Main.java), otwórz terminal w tym folderze i uruchom dwa polecenia: javac Main.java, żeby skompilować kod do bytecode'u, a potem java Main, żeby go uruchomić. Od JDK 11 w przypadku pojedynczego pliku możesz pominąć pierwszy krok i od razu uruchomić java Main.java.

Czym różni się javac od java?

javac to kompilator: czyta kod źródłowy .java i tworzy plik .class pełen bytecode'u. java to launcher: uruchamia JVM i wykonuje bytecode z pliku .class. Kompilujesz raz przez javac, a potem uruchamiasz przez java tyle razy, ile chcesz.

Dlaczego pojawia się "could not find or load main class"?

Prawie zawsze dlatego, że do java podano złą nazwę. Użyj nazwy klasy, a nie nazwy pliku: java Main, a nie java Main.class czy java Main.java. Upewnij się też, że jesteś w folderze zawierającym Main.class i że nazwa klasy dokładnie zgadza się z nazwą pliku, łącznie z wielkością liter.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ