Java 11

java 11 co nowego

Wraz z nowym cyklem wydawniczym Javy minęły zaledwie 3 miesiące od wydania Javy 10, a już doczekaliśmy się Javy 11. Dla przypomnienia nowy system działa w ten sposób, że jeśli jakąś nową funkcjonalność lub usprawnienie udało się wdrożyć, to wchodzi ona do nowej wersji, natomiast jeśli jest jakieś opóźnienie, to po prostu zostaje to odłożone do kolejnej wersji. Jest to bardzo wygodne podejście, ponieważ nie pojawiają się już sytuacje z tym, że kolejna wersja Javy jest opóźniana np. o kilka miesięcy z powodu pojedynczej funkcjonalności. Lista zmian w Javie 11 nie jest bardzo długa, ale na kilka elementów szczególnie warto zwrócić uwagę z punktu widzenia dewelopera.

Java FX 11

java fx logo

Java FX jest technologią do tworzenia graficznego interfejsu użytkownika, która powstała jako zastępstwo Swinga i AWT. Od 2011 roku jest projektem open source, a wraz z pojawieniem się 11 wersji Javy zdecydowano, że nie będzie ona już częścią JDK, zamiast tego będzie dostępna do pobrania niezależnie. Z jednej strony może to wyglądać tak, jakby Oracle chciało się odciąć od JavyFX, ale z drugiej daje szansę na szybszy rozwój, niezależny od samej Javy. Z punktu widzenia dewelopera najważniejsze jest, żeby od teraz pamiętać o tym, że Javę FX trzeba do swojego projektu po prostu dołączyć. Java FX 11 wprowadza też kilka nowości do samej biblioteki. Najciekawsza to chyba wprowadzenie publicznego FX Robot API, które jest odpowiednikiem API Robot z pakietu AWT. Pozwala ono na symulowanie interakcji użytkownika - wciskania klawiszy, klikania przycisków myszy, przesuwania kursora, czy robienia zrzutów ekranu. Wszystko to może być przydatne np. do napisania prostego bota do gry. Powstała także nowa strona projektu, gdzie znajdziemy dokumentację i przykłady zastosowań: openjfx.io

Skrypty

Do tej pory w celu uruchomienia dowolnej aplikacji napisanej w Javie trzeba było wykonać kilka czynności. Napisać kod, skompilować go i dopiero uruchomić na wirtualnej maszynie. W Javie 11 wprowadzono możliwość bezpośredniego uruchamiania kodów, które znajdują się w pojedynczym pliku z kodem źródłowym . Przypomnijmy, że w Javie 9 dodano JShell - interaktywny interpreter, który pozwala w wygodny sposób wykonywać kod Javy i w prosty sposób np. testować proste rzeczy bez konieczności uruchamiania środowiska. Powodem wprowadzenia tej zmiany jest m.in. zmniejszenie progu wejścia do nauki języka, dzięki temu zmniejsza się ilość ceremoniałów potrzebnych do uruchomienia najprostszego hello world. Kompilacja, uruchamianie, javac, java, wirtualna maszyna - dla osoby, która chce po prostu wydrukować kawałek tekstu w konsoli mogło się to wydawać dużo. Po drugie to nowe podejście może zwyczajnie usprawnić pisania prostych skryptów, które usprawnią nam codzienną pracę. Można teraz tak naprawdę na szybko naskrobać coś w zwykłym notatniku i szybko to uruchomić nie robiąc sobie jednocześnie na dysku śmietnika ze skompilowanymi plikami .class. Mając teraz następującą klasę:

public class ExampleScript {
	public static void main(String[] args) {
		int x = 5;
		int y = 10;
		System.out.println(x + y);
	}
}

Możemy ją uruchomić korzystając bezpośrednio z polecenia java.

java console

Nashorn Javascript Engine depreacted

Java od bardzo dawna posiadała silnik pozwalający wykonywać kod JavaScript. Nashorn wprowadzony w Javie 8 został dodany jako zastępstwo silnika Rhino, a teraz, wraz z wydaniem Javy 11, zostaje on oznaczony jako deprecated. Wynika to głównie z tego, że standard ECMAscript (którego JavaScript jest główną implementacją) rozwija się w ostatnich latach na tyle szybko, że twórcy Nashorna nie są w stanie nadążyć z jego rozwojem przy zapewnieniu jednocześnie odpowiedniej jakości wolnej od błędów. Biorąc pod uwagę fakt, że w bardzo dynamicznym tempie rozwija się projekt GraalVM, który pozwoli uruchamiać nie tylko kod JavaScript, ale także kod napisany w wielu innych językach, to zmiana ta w perspektywie czasu nie będzie aż tak dotkliwa. Prawdopodobnie w kolejnych wersjach Javy Nashorn zostanie całkowicie usunięty, więc jeśli wasze aplikacje go wykorzystują, to potrzebne będą zmiany.

Czyszczenia API ciąg dalszy

Java 10 była pierwszą wersją Javy, w której zdecydowano się usunąć wybrane elementy API. Dotyczyło to głównie elementów, które oznaczone zostały jako @Deprecated już w Javie 1.2, jednak ze względu na duży nacisk na kompatybilność wsteczną "śmieci" takie pozostawały dostępne. Przypomnijmy, że jest to kontynuacja wprowadzenia w Javie 9 flagi forRemoval do adnotacji @Deprecated , która pozwala teraz oznaczać elementy API w taki sposób, aby poinformować użytkowników, które elementy są odradzane do użycia, a które zostaną usunięte w przyszłej wersji Javy. O ile w Javie 10 usunięto tylko pojedyncze metody, tak w Javie 11 usunięto już całe wybrane moduły, głównie te, które związane były z Javą EE i nigdy nie powinny się tu znaleźć. Usunięto m.in. moduły JAXB, JAX-WS, JTA, CORBA . Usunięto też m.in. metodę destroy() z klasy Thread, która w rzeczywistości nigdy nie została zaimplementowana.

Drobne usprawnienia API

Z punktu widzenia kodu nie pojawiają się wielkie zmiany, ale jest kilka przyjemnych udogodnień.

  • Metody związane z białymi znakami - isBlank(), strip() , stripLeading() , stripTrailing()
  • metoda repeat(int repeats)
  • metoda lines() zwracająca strumień z wierszami tekstu
String repeat = "ABC".repeat(5);
System.out.println(repeat);
//ABCABCABCABCABC

String whitespaces = "   some text   \n";
System.out.println(whitespaces.stripLeading());
//some text   \n
System.out.println(whitespaces.stripTrailing());
//   some text
System.out.println(whitespaces.strip());
//some text

System.out.println("".isBlank());
//true
System.out.println("    ".isBlank());
//true

"Ania\nKasia\nBasia".lines()
        .map(String::length)
        .forEach(System.out::println);

Doczekaliśmy się także usprawnień w pakiecie NIO. Od teraz w celu zapisania tekstu do pliku nie będzie już potrzebne definiowanie BufferedWritera , zamiast tego do dyspozycji dostajemy wygodną metodę Files.writeString() . Analogiczną metodę dostajemy także do odczytu - Files.readString() . Powstała też metoda do porównania dwóch plików - Files.isSameFile().

Files.writeString(Path.of("plik.txt"), "Jakiś napis");
String text = Files.readString(Path.of("plik.txt"));
System.out.println(text);
//Jakiś napis

Tak proste, a jak długo musieliśmy na to czekać. Oprócz powyższych zmian w API doszukalibyśmy się jeszcze sporej listy podobnych drobnych dodatków.

var w wyrażeniach lambda

W wyrażeniach lambda można teraz używać słowa var jako definicji typu.

List notBadWords = Files.lines(Path.of("plik.txt"))
        .filter((var s) -> s.contains("kur"))
        .collect(Collectors.toList());

Nie jest to może zbyt ekscytujące, bo przecież w wyrażeniach lambda działa automatyczne wnioskowanie typów:

List notBadWords = Files.lines(Path.of("plik.txt"))
        .filter(s -> s.contains("kur"))
        .collect(Collectors.toList());

Dzięki temu usprawnieniu można jednak używać w wyrażeniach lambda także adnotacji, co może być przydatne jeśli nazwy typów będą długie.

Inne

Wprowadzono także dwa dodatkowe garbage collectory. Pierwszy o nazwie Epsilon jest bardzo nietypowy. Jego zadaniem jest nie odśmiecanie pamięci, co może wydawać się absurdem, ale może to być bardzo przydatne do celów testowych. Drugi o nazwie ZGC ma być bardzo wydajny w wielogigabajtowych scenariuszach. Podsumowując - pomimo, że Java 11 nie przynosi żadnych rewolucyjnych zmian, to biorąc pod uwagę, że od Javy 10 minęły zaledwie 3 miesiące, to widać konsekwentny i zauważalny postęp. Osobiście z największą niecierpliwością czekam jednak na nowości z projektu Amber, które mogą mocno wpłynąć na kod pisany w Javie, tak jak było to w przypadku Javy 8.

Dyskusja i komentarze

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