Java 21 Yenilikleri (2023, LTS)
Java 21, Java 17'den sonraki büyük LTS sürümüdür ve son yılların en önemli sürümlerinden biridir. Java 19-20 boyunca önizleme olarak olgunlaşan büyük özellikleri standartlaştırdı: sanal thread'ler, record patterns, sw…
Java 21 Yenilikleri (2023, LTS)
Java 21, Java 17'den sonraki büyük LTS sürümüdür ve son yılların en önemli sürümlerinden biridir. Java 19-20 boyunca önizleme olarak olgunlaşan büyük özellikleri standartlaştırdı: sanal thread'ler, record patterns, switch pattern matching ve sequenced collections. Bugün yeni projeler için önerilen LTS tabanıdır. Bu konu, Java 21'in getirdiklerini karşılaştırmalı, çalışan örneklerle ele alır.
Sequenced Collections (JEP 431)
Uzun süredir eksik olan bir tutarlılık: ilk/son elemana erişim ve ters sıralama, koleksiyona göre
farklıydı (list.get(0), list.get(size-1), deque.getFirst()...). Java 21 ortak arayüzler
getirdi — SequencedCollection, SequencedSet, SequencedMap:
liste.getFirst(); liste.getLast(); liste.addFirst(x); liste.addLast(x); liste.removeFirst(); liste.removeLast(); liste.reversed(); // ters sıralı GÖRÜNÜM
Artık List, Deque, LinkedHashSet, LinkedHashMap hepsi aynı net API'yi sunar. Örnek 1
(./Ornek1.java) eski get(0)/get(size-1) ile yeni API'yi karşılaştırır.
Virtual Threads standart (JEP 444)
Java 19'da önizleme olan sanal thread'ler standartlaştı: JVM'in yönettiği, milyonlarca tane ucuza oluşturulabilen hafif thread'ler. G/Ç ağırlıklı sunucularda "thread başına istek" modelini basit, bloklayan kodla ölçekler — karmaşık asenkron/reaktif kod gerekmez:
try (var exec = Executors.newVirtualThreadPerTaskExecutor()) { for (int i = 0; i < 100_000; i++) exec.submit(() -> { /* G/Ç işi */ }); }
Record Patterns + Pattern Matching for switch standart (JEP 440, 441)
İkisi de standartlaştı ve birlikte çok güçlüdür — switch'te tip + iç yapı + koruyucu (guard)
ile dallanma:
switch (olay) { case Tikla(Konum(var x, var y), var dugme) when dugme == 2 -> "sağ tık @(" + x + "," + y + ")"; case Kaydir(var m) -> "kaydır " + m; case Yaz(var metin) -> "yaz: " + metin; }
Örnek 2 (./Ornek2.java) record patterns, switch pattern matching (guard'larla) ve sanal
thread'leri bir arada gösterir.
Diğer Java 21 yenilikleri
- Generational ZGC (JEP 439): kuşak-temelli, çok düşük gecikmeli çöp toplama.
- Önizleme: String Templates (
STR."Merhaba \{ad}"— gömülü ifadeli string), Unnamed Patterns & Variables (_— kullanılmayan değişken/desen), Structured Concurrency. - Anahtar koleksiyonlar için
HashMapön-boyutlandırma yardımcıları,Math.clampvb.
Geçiş notu (17 → 21)
17'den 21'e geçiş genelde düşük riskli, yüksek kazançlıdır (topic 21). En büyük kazanç sanal
thread'lerdir. Dikkat: sanal thread kullanırken synchronized blokların içindeki uzun işlemler
"pinning"e yol açabilir (kritik bölümlerde ReentrantLock tercih et — Java 24 bu kısıtı büyük
ölçüde kaldırdı).
Özet
Java 21'in (LTS) standartlaştırdığı büyük özellikleri öğrendik: Sequenced Collections (ortak ilk/son/ters API; Örnek 1), virtual threads, record patterns ve switch pattern matching (Örnek 2), Generational ZGC; String Templates/Unnamed Patterns önizlemelerine değindik. Java 21, modern Java'nın bugünkü önerilen tabanıdır. Sırada, JDK 21'de çalışmayan ama bilmen gereken en yeni sürümler: Java 22 (kavramsal).
▶ Kod Örnekleri(2)
Ornek1
çalıştırılabilir1// Ornek1: Java 21 (LTS) — Sequenced Collections (sıralı koleksiyonlar, JEP 431).
2// Çalıştırma: java Ornek1.java
3import java.util.ArrayList;
4import java.util.LinkedHashSet;
5import java.util.List;
6import java.util.SequencedCollection;
7
8public class Ornek1 {
9
10 public static void main(String[] args) {
11 List<String> liste = new ArrayList<>(List.of("giriş", "işlem", "rapor", "çıkış"));
12
13 // ÖNCESİ: ilk/son elemana erişim tutarsız ve hantaldı.
14 String ilkEski = liste.get(0);
15 String sonEski = liste.get(liste.size() - 1); // size-1 her seferinde
16
17 // SONRASI (Java 21): tüm sıralı koleksiyonlarda ORTAK, net metotlar.
18 String ilkYeni = liste.getFirst();
19 String sonYeni = liste.getLast();
20 System.out.println("ilk: " + ilkEski + "/" + ilkYeni + ", son: " + sonEski + "/" + sonYeni);
21
22 // Baştan/sondan ekle-çıkar (List'te de artık var):
23 liste.addFirst("BAŞLANGIÇ");
24 liste.addLast("BİTİŞ");
25 System.out.println("addFirst/addLast: " + liste);
26
27 // reversed(): ters sıralı GÖRÜNÜM (kopya değil) — tek metotla.
28 System.out.println("reversed(): " + liste.reversed());
29
30 // Aynı arayüz LinkedHashSet'te de çalışır (sıralı küme):
31 LinkedHashSet<Integer> kume = new LinkedHashSet<>(List.of(10, 20, 30));
32 System.out.println("\nLinkedHashSet ilk/son: " + kume.getFirst() + "/" + kume.getLast());
33 System.out.println("reversed: " + kume.reversed());
34
35 // Ortak tip: SequencedCollection (List, Deque, LinkedHashSet hepsi bunu uygular).
36 SequencedCollection<String> sc = liste;
37 System.out.println("\nSequencedCollection olarak ilk: " + sc.getFirst());
38
39 System.out.println("""
40
41 --- Java 21: Sequenced Collections (JEP 431) ---
42 ÖNCESİ: ilk/son elemana erişim koleksiyona göre FARKLIYDI (list.get(0), deque.getFirst(),
43 son için list.get(size-1)...) ve 'tersten gez' için ayrı yollar gerekiyordu.
44 SONRASI: ORTAK arayüzler -> SequencedCollection/SequencedSet/SequencedMap.
45 getFirst()/getLast(), addFirst()/addLast(), removeFirst()/removeLast(), reversed().
46 Artık List, Deque, LinkedHashSet, LinkedHashMap aynı net API ile baş/son/ters işlemleri sunar.
47 Küçük ama günlük hayatı kolaylaştıran, uzun süredir beklenen bir tutarlılık.""");
48 }
49}Ornek2
çalıştırılabilir1// Ornek2: Java 21 — record patterns + switch pattern matching + virtual threads STANDART.
2// Çalıştırma: java Ornek2.java
3import java.util.concurrent.Executors;
4import java.util.concurrent.atomic.AtomicInteger;
5
6public class Ornek2 {
7
8 sealed interface Olay permits Tikla, Kaydir, Yaz {}
9 record Konum(int x, int y) {}
10 record Tikla(Konum konum, int dugme) implements Olay {}
11 record Kaydir(int miktar) implements Olay {}
12 record Yaz(String metin) implements Olay {}
13
14 static String isle(Olay o) {
15 // record patterns + switch pattern matching + guards — HEPSİ Java 21'de STANDART.
16 return switch (o) {
17 case Tikla(Konum(var x, var y), var dugme) when dugme == 2 -> "sağ tık @(" + x + "," + y + ")";
18 case Tikla(Konum(var x, var y), var dugme) -> "tık @(" + x + "," + y + ") dugme=" + dugme;
19 case Kaydir(var m) when m > 0 -> "yukarı kaydır " + m;
20 case Kaydir(var m) -> "aşağı kaydır " + m;
21 case Yaz(var metin) -> "yaz: " + metin;
22 };
23 }
24
25 public static void main(String[] args) throws InterruptedException {
26 // record patterns + switch (standart):
27 Olay[] olaylar = { new Tikla(new Konum(10, 20), 1), new Tikla(new Konum(5, 5), 2),
28 new Kaydir(3), new Kaydir(-2), new Yaz("merhaba") };
29 for (Olay o : olaylar) System.out.println(" " + isle(o));
30
31 // Virtual threads (standart): binlerce görev ucuza.
32 AtomicInteger biten = new AtomicInteger();
33 try (var exec = Executors.newVirtualThreadPerTaskExecutor()) {
34 for (int i = 0; i < 5_000; i++) exec.submit(() -> {
35 try { Thread.sleep(20); } catch (InterruptedException ignored) {}
36 biten.incrementAndGet();
37 });
38 }
39 System.out.println("\n5.000 sanal thread görevi bitti: " + biten.get());
40
41 System.out.println("""
42
43 --- Java 21 (LTS): standartlaşan büyük özellikler ---
44 Java 19-20'de önizleme olanların hepsi Java 21'de STANDART oldu:
45 - Virtual Threads (JEP 444): ucuz, ölçeklenebilir eşzamanlılık.
46 - Record Patterns (JEP 440) + Pattern Matching for switch (JEP 441): tip+iç yapı+guard ile dallanma.
47 - Sequenced Collections (JEP 431): ortak ilk/son/ters API (Örnek 1).
48 - Generational ZGC (JEP 439): düşük gecikmeli, kuşak-temelli çöp toplama.
49 ÖNİZLEME (21'de): String Templates (STR.\"...\"), Unnamed Patterns/Variables (_), Structured Concurrency.
50 17 -> 21 geçişi genelde DÜŞÜK RİSKLİ, YÜKSEK KAZANÇLIDIR (topic 21). Bugünün önerilen LTS tabanı.""");
51 }
52}