Uruchamianie programów w Javie 21 i nowszych

Java jest językiem programowania, w którym napisanie pierwszego programu było zdecydowanie bardziej skomplikowane niż w wielu innych językach, szczególnie tych skryptowych. Pomimo iż Java posiada wiele zalet, to często jednak pierwsze wrażenie i trudność w napisaniu przysłowiowego Hello World może zadecydować o tym, czy ktoś zdecyduje się na ten, czy inny język programowania. Twórcy Javy dostrzegli ten problem i w wersji 21 wprowadzony został elastyczny protokół startowy (elastic launch protocol), dzięki któremu tworzenie i uruchamianie prostych programów wymaga zdecydowanie mniej ceremoniałów.

Java 8

W celu uruchomienia programu napisanego w Javie 8 lub starszej programista musiał najpierw utworzyć plik z kodem źródłowym, który ma rozszerzenie .java, następnie kod taki należało poddać kompilacji przy pomocy polecenia javac, żeby na końcu uruchomić powstały plik z rozszerzeniem class, korzystając z polecenia java. Dodatkowo każdy program powinien posiadać specjalną metodę main, od której rozpoczyna się działanie programu.

Java 9

Pewne zmiany w uruchamianiu aplikacji zaszły już w 2016 roku wraz z Javą 9, kiedy w JDK pojawiło się nowe narzędzie o nazwie jshell. Jest to interaktywny interpreter, w którym możemy na bieżąco wpisywać instrukcje Javy i testować je w prosty sposób, bez tworzenia pliku z rozszerzeniem .java, bez definiowania metody main i bez procesu kompilowania. Narzędzie to może się dobrze sprawdzić w testowaniu bardzo prostych rzeczy i w procesie nauki, jednak nie mamy tutaj do końca poczucia tworzenia pełnoprawnego programu.

Elastyczny protokół startowy

W Javie 21 postanowiono rozwiązać kwestię łatwiejszego uruchamiania programów systemowo i dać większą swobodę w kontekście definiowania punktu startowego programu. Ma to na celu przede wszystkim zmniejszyć próg wejścia do języka dla początkujących. Omawiane zmiany zostały nazwane elastycznym protokołem startowym (elastic launch protocol).

Przed Javą 21 programy miały punkt startowy w postaci publicznej i statycznej metody main, która dodatkowo posiada parametr będący tablicą String, np.:

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

Dla programisty Javy choćby z niewielkim doświadczeniem nie ma tutaj nic zaskakującego, jednak dla początkujących jest tutaj sporo elementów, które wymagają wyjaśnienia:

  • czym jest class?
  • co oznacza public?
  • co oznacza static?
  • co oznacza void?
  • czym jest String[] args?
  • czy wspomniane elementy są wymagane?

W praktyce nauka programowania w Javie zazwyczaj rozpoczyna się od stwierdzenia "musisz zapisać wszystkie te elementy, ale na razie nie będziemy ich omawiać, zrozumiesz je za jakiś czas". Takie podejście z dydaktycznego punktu widzenia nie jest optymalne, bo po co w ogóle coś zapisywać, jeżeli nie ma to wpływu na działanie programu.

Nienazwane klasy

Pierwszą nowością są nienazwane klasy (unnamed classes), których nazwa jednoznacznie mówi o tym, czym właściwie są. We wcześniejszych wersjach Javy każda klasa musiała mieć nazwę i dopiero wtedy mogliśmy w niej zapisywać pozostały kod, np. pola, konstruktory, czy metody. Teraz nie będzie już takiej potrzeby. W pliku z rozszerzeniem .java możemy od razu zapisać kod metody

Nienazwane klasy muszą znajdować się w nienazwanym pakiecie, tzn. nie mogą posiadać deklaracji pakietu, ale co ciekawe importy są już jak najbardziej dozwolone.

W klasie nienazwanej oprócz metody main mogą znajdować się także inne elementy takie jak metody, czy pola, które używają różnych specyfikatorów dostępu, ale nie mogą posiadać konstruktorów innych niż konstruktor domyślny, który dodawany jest automatycznie przez kompilator. Przykładowy program zapisany w klasie nienazwanej może wyglądać w ten sposób:

import java.util.Scanner;

private static Scanner scan = new Scanner(System.in);

public static void main(String[] args) {
    String name = getName();
    System.out.printf("Cześć %s%n", name);
}

private static String getName() {
    System.out.println("Podaj imię:");
    String name = scan.nextLine();
    return name;
}

W praktyce klasy nienazwane są odpowiednikiem anonimowej klasy wewnętrznej utworzonej w następujący sposób:

new Object() {
    // ciało nienazwanej klasy
}.main();

main jako metoda instancji

Powyżej widzisz, że od Javy 21 programy nie muszą być jawnie zapisane w żadnej klasie, ale z perspektywy początkującego programisty eliminuje to tylko jeden element, który trzeba było zapisać, a ciężko go na początku wytłumaczyć. Co jednak z pozostałymi public, static, void, czy String[]?

Elastyczny protokół startowy nie wymaga już statycznej metody main, ale zamiast tego możemy wykorzystać instancyjne metody main, które dodatkowo będą pozbawione parametru z tablicą Stringów.

W Javie 21 wszystkie poniższe zapisy stanowią więc kompletne programy.

public void main(String[] args) {
    System.out.println("Hello World 21");
}
void main(String[] args) {
    System.out.println("Hello World 21");
}
void main() {
    System.out.println("Hello World 21");
}

W ten sposób do wytłumaczenia pozostaje nam już tylko słowo void, a całą resztę możemy wprowadzać systematycznie wraz z poznawaniem kolejnych elementów języka.

Programy zapisane w jednym pliku

W celu uruchomienia powyższych programów kod należy najpierw skompilować używając kompilatora javac, a następnie je uruchomić przez polecenie java. W Javie 21 omawiane zmiany mają status preview feature, więc należy dodać jeszcze flagę --enable-preview i --source, albo --release, co finalnie wygląda tak:

javac --source 21 --enable-preview HelloWorld.java
java --enable-preview HelloWorld

W Javie 11 wprowadzono jednak jeszcze jedno usprawnienie, dzięki któremu uruchamianie programów zapisanych w jednym pliku z kodem źródłowym nie wymaga jawnej kompilacji. Zamiast dwóch poleceń możemy się ograniczyć do polecenia java:

java --enable-preview --source 21 HelloWorld.java

Gdy do elastycznego protokołu startowego nie będzie większych uwag i ostatecznie trafi on do Javy, to całość sprowadzi się po prostu do prostego polecenia:

java HelloWorld.java

Z perspektywy początkującego pierwsze wrażenia z Javą powinny być więc zdecydowanie bardziej pozytywne, niż miało to miejsce przez ostatnich 20 lat i powinno, choć początkowo będzie wprowadzało zapewne trochę zamieszania, szczególnie wtedy, gdy ktoś będzie korzystał ze starszych materiałów edukacyjnych.

Po więcej informacji zajrzyj tutaj: https://openjdk.org/jeps/445 https://openjdk.org/jeps/330

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.