Java 9
Java 9 ile gelen modül sistemi, JLink, Interface Private Methods, JShell, HTTP/2 Client, Reactive Streams veya reaktif programlama gibi özelliklerin örnekleri ve kullanımı ile yer alıyor.
Java Modül Sistemi
Java 9 öncesi modül sistemi maven, gradle gibi araçlar ile sağlanıyordu.
Java 9 modül sistemi ile birlikte JDK içerisinde modül sistemi özelliği gelmiş oldu.
Modül sistemi özelliği ile birlikte geliştirmeler modüllere göre yapılarak özel bir dosya (module-info) ile projeye dahil edilir.
Math Lib
module-info.java
module MathLib {
exports mathlib;
}
Sum.java
package com.yusufsezer.mathlib;
public class Sum {
private final long number1;
private final long number2;
public Sum(long number1, long number2) {
this.number1 = number1;
this.number2 = number2;
}
public long result() {
return number1 + number2;
}
}
Java Application
module-info.java
module JavaApplication {
requires MathLib;
}
App.java
package com.yusufsezer;
import com.yusufsezer.mathlib.Sum;
public class App {
public static void main(String[] args) {
Sum sum = new Sum(10L, 10L);
System.out.println(sum.result());
}
}
JLink
Java 9 ile birlikte tüm Java paketler modüllere ayrılmıştır.
Modül sistemi ile birlikte sadece ihtiyaç duyulan modülleri içeren JDK oluşturmayı sağlayan jlink aracı gelmiştir.
Araç ile kullanılacak modülleri belirleyerek JDK içeriğinin sadece ihtiyaç duyulan modüllerin yer alması sağlanır.
jlink --module-path --add-modules --limit-modules --output
Yukarıda hazırlanmış modülün paketlenmesi için aşağıdaki komudun çalıştırılması yeterli olacaktır.
jlink --add-modules mathlib --output yusufsezerjre
Komut çalıştırıldıktan sonra eklenen modüllerin yer aldığı bir JDK oluşacaktır.
Interface Private Methods
Java 8 sürümünde arayüzlere eklenen default ve static method özelliği ile arayüzlere varsayılan ve statik metot ekleme özelliği gelmişti.
Java 9 ile birlikte artık arayüzlerde private method tanımı yapılabiliyor.
Arayüz içerisinde yer alan private metotlar sadece arayüz içerisindeki metotlar tarafında kullanılabilir.
interface ISum {
default int addEvenNumbers(int... nums) {
return add(n -> n % 2 == 0, nums);
}
default int addOddNumbers(int... nums) {
return add(n -> n % 2 != 0, nums);
}
private int add(IntPredicate predicate, int... nums) {
return IntStream.of(nums)
.filter(predicate)
.sum();
}
}
public class App implements ISum {
public static void main(String[] args) {
int result = new App().addEvenNumbers(IntStream.range(0, 100).toArray());
System.out.println(result);
}
}
JShell
Bir çok programlama dili tarafından desteklenen REPL yani Read-Eval-Print-Loop desteği Java 9 ile birlikte Java programlama diline eklenmiştir.
Bu özellik sayesinde Java kodlarını proje açmadan jshell aracı ile kolayca yapmayı sağlar.
Aracı çalıştırmak için JDK dizinini işletim sistemi ortam değişkenlerine ekledikten sonra komut yorumlayıcısına (CMD, PowerShell, Bash) jshell yazarak araca erişim sağlanır.
Araç açıldıktan sonra Java kodları yazılarak çalıştırılabilir.
Örneğin; Aşağıdaki komudu yazıp enter tuşuna basıldığına ekrana “Merhaba JShell” yazacaktır.
System.out.println("Merhaba JShell");
HTTP/2 Client
HttpClient, HttpRequest and HttpResponse sınıfları Java içerisine eklenerek HTTP 2 desteği getirildi.
public class App {
public static void main(String[] args) throws IOException, InterruptedException {
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest
.newBuilder()
.uri(URI.create("https://www.yusufsezer.com/"))
.GET()
.build();
HttpResponse response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
Sınıflar incelenerek istemci, istek ve cevap ile ilgili bilgilere erişim sağlanabilir.
HttpClient sınıfında yer alan newWebSocketBuilder() metodu ile websocket işlemleri yapmayı sağlar.
Process API
İşlemleri yönetmek için kullanılan Process API geliştirilerek yeni sınıf, arayüz ve metotlar eklenmiştir.
public class App {
public static void main(String[] args) {
ProcessHandle
.allProcesses()
.forEach((process) -> {
System.out.println("Process ID: " + process.pid());
System.out.println("Process alive: " + process.isAlive());
ProcessHandle.Info info = process.info();
System.out.println(info);
});
}
}
Process API yeni bir process oluşturmayı da sağlar.
public class App {
public static void main(String[] args) throws IOException {
String javaProcess = ProcessHandle.current().info().command().get();
ProcessBuilder processBuilder = new ProcessBuilder(javaProcess, "-version");
processBuilder.inheritIO().start();
}
}
Immutable Collections
Java 9 ile birlikte Immutable koleksiyonlar oluşturmak için List, Set, Map gibi arayüzlere of metodu eklenmiştir.
public class App {
public static void main(String[] args) {
List nameList = List.of("Yusuf", "Sefa", "Sezer");
nameList.forEach(System.out::println);
Set nameSet = Set.of("Yusuf", "Sefa", "Sezer");
nameSet.forEach(System.out::println);
Map<String, String> nameMap = Map.of("firstName", "Yusuf",
"middleName", "Sefa",
"lastName", "Sezer");
nameMap.forEach((key, value) -> System.out.println(key + ": " + value));
}
}
Stream API
Stream API özelliğine takeWhile, dropWhile, ofNullable, iterate metotları eklenmiştir.
public class App {
public static void main(String[] args) {
Stream
.iterate(1, i -> i <= 10, i -> ++i)
.forEach(System.out::println);
IntStream
.rangeClosed(1, 10)
.boxed()
.dropWhile(p -> p < 5)
.forEach(System.out::println);
}
}
Platform and JVM Logging
Log veya günlük işlemleri için standart oluşturmak için java.base modülünde yer alan System sınıfına Logger arayüzü eklenmiştir.
Yeni -Xlog argümanı ile loglama işlemini parametrik olarak belirleme özelliği eklenmiştir.
Multi-Release JAR Files
Java sürümlerinin sürekli güncellenmesi ile birlikte oluşan versiyon uyumsuzluğu problemine çözüm olarak birden fazla Java sürümüne göre derleme özelliği eklenmiştir.
Özelliğin kullanımı için ilk olarak farklı Java sürümlerine göre geliştirilen kodlar derlenmelidir.
Derleme işleminden sonra jar aracı ile farklı Java sürümü ile derlenen dosyalar birleştirilmelidir.
jar --create --file BenimProjem.jar -C java-8/out . --release 9 -C java-9/out .
@Deprecated Tag Changes
Herhangi bir metot, sınıf, özellik, paketin kullanımdan kaldırıldığını ifade etmek için kullanılan @Deprecated annotations yeni forRemoval ve since alanları eklenmiştir.
Reactive Streams
Asenkron uygulamalar geliştirmek için Reactive Streams özelliği java.util.concurrent.flow sınıfı, sınıf içerisinde yer alan arayüz ile gelmiştir.
Flow API içerisinde yer alan Publisher gelen istekleri işleyerek Subscriber arayüzünde yer alan metotların çalıştırılmasını sağlar.
Her bir işlem Subscriber arayüzünde tanımlanır ve Subscription ile işlemler arası geçiş yapılır.
public class App {
public static void main(String[] args) throws InterruptedException {
SubmissionPublisher<Integer> publisher = new SubmissionPublisher<>(); // İşlemler
publisher.subscribe(new PrintSubscriber()); // İşlemleri işleyecek Subscriber
for (int i = 1; i < 100; i++) {
publisher.submit(i); // Yeni işlem ekle
}
Thread.sleep(1000);
publisher.close();
}
static class PrintSubscriber implements Subscriber<Integer> {
private Subscription subscription;
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
subscription.request(1); // Sonraki işleme geç
}
@Override
public void onNext(Integer item) {
System.out.println("İşlem sırası: " + item); // İşlemi yap
subscription.request(1); // Sonraki işleme geç
}
@Override
public void onError(Throwable error) {
System.out.println(error.getMessage());
}
@Override
public void onComplete() {
System.out.println("İşlem tamamlandı.");
}
}
}
Try-With-Resources
Java 7, 8 ile gelen ve kaynakların otomatik kapatılması için kullanılan Try-With-Resources özelliği genişletildi.
public class App {
public static void main(String[] args) throws IOException {
String myFile = "yusuf.txt";
BufferedReader mySource = Files.newBufferedReader(Paths.get(myFile));
try (mySource) {
System.out.println(mySource.readLine());
}
System.out.println(mySource.readLine()); //Stream closed
}
}
Try-With-Resources özelliğinin geliştirimesi sayesinde parantez içerisinde yer almayan kaynağın kapatılması sağlandı.
Stack-Walking API
Çalıştırılan komut yığını ile ilgili detaylı bilgi almak için java.lang paketinde yer alan StackWalker eklenmiştir.
Sınıf çalıştırılan komutlarla ilgili daha detaylı bilgi almaya sağlar.
public class App {
public static void main(String[] args) {
method1();
}
private static void method1() {
method2();
}
private static void method2() {
method3();
}
private static void method3() {
StackWalker
.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
.forEach(App::print);
//.forEach(System.out::println);
}
private static void print(StackWalker.StackFrame stackFrame) {
Class<?> c = stackFrame.getDeclaringClass();
int lineNumber = stackFrame.getLineNumber();
String methodName = stackFrame.getMethodName();
System.out.printf("Sınıf: %s, Metot: %-7s, Satır: %s%n",
c.getSimpleName(), methodName, lineNumber);
}
}
Özellik Annotations tabanlı geliştirmelerin yönetimi için faydalı olacaktır.
Optional
Sınıfa yeni metotlar eklenmiştir.
public class App {
public static void main(String[] args) {
// ifPresentOrElse
IntStream.of(1, 2, 4)
//IntStream.of(2, 3, 5)
.filter(i -> i % 3 == 0)
.findFirst()
.ifPresentOrElse(System.out::println, () -> {
System.out.println("Bulunamadı!");
});
// or
char digit = Stream.of('a', 'b', 'c')
.filter(c -> Character.isDigit(c))
.findFirst()
.or(() -> Optional.of('0')).get();
System.out.println(digit);
// stream
OptionalInt opt1 = IntStream.of(2, 5, 6).max();
OptionalInt opt2 = IntStream.of(1, 3, 7).max();
IntStream.concat(opt1.stream(), opt2.stream())
.forEach(System.out::println);
}
}
Diğer
Modül sistemi ve Reaktif programlama Java 9 ile gelen önemli özelliklerdendir.
Ayrıca Arrays, Enumeration, CompletableFuture API, GC (Garbage Collector), Filter Incoming Serialization Data, Deprecate the Applet API, Indify String Concatenation, Enhanced Method Handles, Compact Strings, Parser API for Nashorn, Javadoc Search, HTML5 Javadoc gibi küçük değişikliklerde yer almaktadır.
Modül sistemi ile Java bulut tabanlı, taşınabilir bir platform haline gelmiştir.
Reaktif programlama ile web veya ağ tabanlı uygulamalarda yer alan alt yapı veya veri kaynağı kaynaklı geçikmenin yönetimi daha kolaylaşmıştır.
Java 9 ile birlikte artık Java sürekli güncellenecek bir platform haline gelmiştir.
Java Derslerine buradan ulaşabilirsiniz.
Hayırlı günler dilerim.