Java 9

Paylaş

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.


Bunlarda ilgini çekebilir


Destek almak için tıklayın.