Zima w pełni. Śnieg za oknami i ogólnie panująca poświąteczna nostalgia. Wydaje się, że nic się nie dzieje, ale to tylko pozory.
Wielkimi krokami nadchodzi i jest już coraz bliżej nowa wersja Javy - Java 12.
Z tego tytułu postanowiliśmy cofnąć się nieco wstecz i podsumowować zmiany jakie przyniosły ze sobą trzy ostatnie wersje naszego ulubionego języka.
Postanowiliśmy opisać wszystkie wersje naraz, bo po pierwsze fajnie jest mieć wszystko w jednym miejscu, a po drugie -
o ile Java 8 była wersją przełomową, o tyle kolejne jej wersje wprowadzją tylko lekkie modyfikacje. Choć czy aby na pewno takie lekkie?
Przyjrzyjmy się.
Java 9 - Wrzesień 2017
-
Java Platform Module System - Nowa koncepcja w programowaniu w Javie, którą jest możliwość tworzenia modułów. Moduł w skrócie jest nazwanym
zbiorem pakietów wraz z plikiem opisującym jego zawartość (deskryptorem).
Możemy wyróżnić cztery typy modułów:
-
Systemowe (System Modules) - moduły wbudowane, które możemy wylistować za pomocą komendy list-modules
-
Aplikacyjne (Application Modules) - nasze własne moduły tworzone na rzecz budowanej przez nas aplikacji. Posiadają nazwę
oraz swoją definicje w pliku deskryptora module-info.class.
-
Automatyczne (Automatic Modules) - powstają przez dodanie istniejących plików JAR do ścieżki modułu.
Nazwa modułu będzie stworzona na podstawie nazwy pliku JAR.
-
Anonimowe (Unnamed Modules) - powstają poprzez dodanie klasy bądź pliku JAR do classpath,
zamiast do ścieżki modułu. Taki element zostaje dodany do modułu bez nazwy.
Dzięki wprowadzeniu modułów możemy przygotować aplikację tak, by zamiast zawierania całego JDK, posiadała tylko potrzebne nam zależności.
W ten sposób ograniczamy wielkość takiej aplikacji. Tworzymy minimalny obraz środowiska wykonawczego, zoptymalizowany pod kątem funckjonalności naszej aplikacji.
-
JShell - Rozwiązanie umożliwiające wykonywanie kodu Java bezpośrednio z konsoli. Doskonale nadaje się to do testowania niewielkich fragmentów kodu.
Prostym przykładem wykorzystania może być testowanie wyrażeń regularnych. Dużą zaletą jest to, że aby wykonać kawałek kodu Java nie musimy tworzyć specjalnie
w tym celu klasy oraz metody statycznej main.
JShell bazuje na tzw. interaktywnej pętli odczytu-ewaluacji z ang. Read-Eval-Print-Loop, co tłumaczymy:
-
Read - Wpisz kod
-
Eval - Wykonaj kod
-
Print - Zobacz wynik
-
Loop - Wykonaj ponownie
Dzięki JShell możemy szybko zbadać nowe API, tymbardziej że konsola udostępnia nam uzupełnianie kodu oraz dokumentację.
Tak samo doskonale nadaje się do uczenia Javy, gdyż pozwala pokazać od ręki podstawowe koncepcje bez potrzeby uruchamiania IDE.
-
Nowa wersja HttpClient - ten kto próbował używać starej wersji klienta ten wie, że była ona ciężka w użyciu, stąd stworzenie nowej wersji jest naprawdę wartościową zmianą. Trzeba jednak pamiętać, że nowa wersja
jest narazie częścią modułu incubator, a więc zawiera eksperymentalne API, co oznacza, że wciąż ewoluuje i niektóre rozwiązania mogą się jeszcze nieco zmienić.
Niemniej warto wspomnieć o nowościach:
-
Zastąpienie HTTPURLConnection nową wersją, wygodniejszą w użyciu.
-
Dostarczenie wsparcia dla HTTP 2 oraz dla WebSocketów.
-
Rozpoczęcie procesu łączenia Oracle JDK & OpenJDK - proces ten będzie trwał przez kilka kolejnych releasów Javy. Zunifikowane zostną technikalia, jednak
OpenJDK i OracleJDK będą nadal dostępnymi opcjami. Różnica będzie polegała na dostępności supportu, a także na wprowadzeniu modelu płatnej subskrypcji w ramach OracleJDK.
-
Collection Factory Methods - Nowe metody umożliwiające pracę z kolekcjami:
-
List.of - Tworzenie listy (immutable), na przykład:
List<Integer> numbers = List.of(1, 10, 100);
-
Set.of - Tworzenie zbioru (zgodnie z naturą setów przekazywane wartości nie mogą się duplikować), na przykład:
Set<String> names = Set.of("Kowalski", "Nowak");
-
Map.of - Tworzenie mapy (zgodnie z naturą map przekazujemy klucze i wartości), na przykład:
Map names = Map.of("Lastname1", "Kowalski", "Lastname2", "Nowak");
-
Map.of - Tworzenie mapy na podstawie obiektów Map.entry, na przykład:
Map names = Map.ofEntries(Map.entry("Lastname1", "Kowalski"), Map.entry("Lastname2", "Nowak"));
-
Stream API - nowe metody:
-
Stream<T> takeWhile(Predicate<? super T> predicate)
-
Stream<T> dropWhile(Predicate<? super T> predicate)
-
static Stream<T> ofNullable(T t)
-
static Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
-
Inne drobne zmiany:
-
Nowe kolektory w strumieniach
-
Nowe metody w ramach Optional
-
Prywatne metody w interfejsach - mogą być używane w ramach metod domyślnych, a jednocześnie nie są widziane przez klasy implementujące.
Java 10 - Marzec 2018
-
Wnioskowanie typu zmiennych lokalnych (Local-variable Type Inference) - od teraz, w przypadku gdy kompilator jest w stanie wywnioskować
typ zmiennej lokalnej, zmienna taka nie musi być deklarowana w postaci konkretnego typu. Wystarczy, że określimy ją za pomocą słowa var:
W powyższym przykładzie var zastępuje - wymagane do tej pory - użycie typu String. Uwaga. Var
nie jest słowem kluczowym, a więc teoretycznie może być rownież używane jako nazwa zmiennej, czy też nazwa pakietu. Niemniej powinniśmy tego unikać. Var
nie zostało określone jako słowo kluczowe głównie po to, aby zachować kompatybilność wsteczną naszego kodu.
Należy pamiętać, że stosując lambdy musimy jawnie zadeklarować docelowy typ, więc w tym przypadku nie możemy użyć wnioskowania typu.
W wielu przypadkach było by to utrudnieniem dla programisty, gdyż wymagałoby odgadywania jaki typ może być zwracany przez wyrażenie lambda.
-
Nowe rozwiązania podnoszące wydajność:
-
Wprowadzenie równoległego działania procesów w ramach pełnego odśmiecania (Garbage Collection).
-
Przyspieszenie startu maszyny wirtualnej (JVM), co zostało osiągnięte dzięki wprowadzeniu współdzielonej biblioteki przechowującej metadane klas.
Ich stan może być przenoszony między maszynami wirtualnymi.
-
Rozwinięto współpracę z kontenerami typu Docker, np. umożliwione zostało wykrycie uruchomienia Javy w ramach kontenera, co przekłada się na
lepsze wykorzystanie zasobów. Możemy na przykład sami konfigurować stopień zaangażowania zasobów przez maszynę wirtualną. Jest to jednak na razie dostępne
tylko dla Dockera i to uruchomionego na maszynie z zainstalowanym systemem Linux.
Java 11 - Wrzesień 2018
-
Wprowadznie LTS (Long Term Support) - Oracle wprowadził 3 letni okres utrzymywania głównych releasów Javy wydawanych co 3 lata. Pierwszym jest właśnie release w wersji 11,
kolejnymi 17 i 23. Do tego wymagana jest subskrypcja, która jest płatna. Jeśli jej nie wykupimy nasz support (krótkoterminowy) będzie dostępny tylko przez pół roku
(między wersjami). Zatem jeśli nie chcemy płacić, to najlepiej będzie aktualizować wersje co pół roku, co oczywiście może być problematyczne, szczególnie w przypadku dużych systemów.
-
Uruchomienie pliku Java bez ręcznej kompilacji - dostajemy możliwość uruchomienia pojedynczego pliku Java bez jego wcześniejszej ręcznej kompilacji za pomocą javac!
Uruchamiamy plik wykonując polecenie:
java HelloJavappa.java
Plik jest kompilowany w locie i od razu wykonywany.
-
Tworzenie skryptów z większa ilością kodu Java w środku, co pozwala nam na uruchomienie takiego skryptu bez potrzeby angażowania IDE.
-
Usunięcie Enterprise API's z JDK - kilka znanych technologii zostało usuniętych z JDK SE. Są one oczywiście dostępne nadal w ramach Java EE.
Usunięto JAXB, JAX-WS, JX-WS Annotations, CORBA, JTA, JavaBeansActivation. Jeśli zatem używaliśmy API jednej z wymienionych technologii
korzystając z JDK SE, wówczas po podłączeniu Javy 11 projekty te przestaną się kompilować. Należy wtedy dodać zewnętrzne zależności
do tych technologii.
-
Nowa wersja HttpClient - od Javy 11 nowy klient jest już w pełni skończony i zostaje wyprowadzony z inkubatora do oficjalnego modułu.
-
TLS 1.3 (Transport Layer Security) zaimplementowany w JDK - kilka algorytmów zostało okrojonych, a kilka zostało zmienionych.
-
Ciekawsze zmiany w ramach klas i metod:
-
Metoda klasy Files - readString. Wykonanie metody readString(path)
zwróci tekst z pliku. Co najważniejsze metoda sama obsłuży otwieranie i zamykanie pliku! Nie musimy już tym w ogóle zarządzać.
Można ją wykonać podając dodatkowo kodowanie (domyślnie otwiera ona pliki z kodowaniem UTF-8).
-
Metoda klasy Files - writeString. Wykonanie metody writeString(path, charSequence, openOption)
zapisze tekst do pliku. Ostatni parametr to obiekt klasy OpenOption, w którym możemy określić sposób otwarcia pliku (append, overwrite itp.).
-
Metoda klasy String - repeat. Wykonanie metody "Javappa ".repeat(10)
powtórzy 10-krotnie słowo Javappa.
-
Metoda klasy String - isBlank. Wykonanie metody someString.isBlank()
zwróci nam informację o tym czy zmienna zawiera tekst czy też nie.
-
Metoda klasy String - strip. Wykonanie metody "Javappa \u2005".strip()
zwróci nam sam text bez białych znaków. Podobnie działa metoda trim, z tą różnicą, że nie usuwa ona białych znaków podanych w Unicodzie.
Metoda strip potrafi to zrobić.
-
Metoda klasy String - lines. Wykonanie metody "Jacek\nJanek\nJarek\nJavappa\n".lines()
stworzy nam strumień stringów. Iterując po strumieniu dostaniemy się do każdej wartości.
-
Pojawia się możliwość użycia słowa var przed parametrami w wyrażeniach lambda. Przydaje się to gdy chcemy opisać te parametry
adnotacjami. Wtedy wymagane jest podanie typu.
-
Inne ciekawsze zmiany:
-
Usunięcie technologii Appletów.
-
Usunięcie Java Web Start.
-
Przeniesienie JavaFX z JDK do projektu OpenJFX.
-
Nashorn został zdeprecjonowany (przeznaczony do usunięcia w przyszłości).
-
Pojawienie się dwóch nowych Garbage Collectorów: Epsilon GC i Z Garbage Collector (oba są eksperymentalne).
Jak widać lista zmian jest dosyć długa i z pewnością znajdują się tutaj takie elementy, na które należy zwrócić wiekszą uwagę. Nam w szczególności
podobają się całkiem nowe rozwiązania, takie jak Java Platfrom Module System, czy konsola JShell. Za bardzo przydatne uważamy również wprowadzenie nowych metod do obsługi plików,
jak również pojawienie się (wreszcie) nowej wersji klienta HTTP. Modyfikacje te z pewnością nie są równie rewolucyjne jak te wprowadzone w wersji 8, ale po głębszym zastanowieniu
stwierdzamy, że nie nazwalibyśmy ich również lekkimi.
Autor: Jarek Klimas
Data: 05 stycznia 2019
Labele:Backend, Poziom podstawowy, Java, Spring
Masz pytanie odnośnie zagadnienia omawianego w artykule?
Coś, co napisaliśmy, nie zaspokoiło Twojego głodu wiedzy?
Daj nam znać co myślisz i skomentuj artykuł na facebooku!