Java 25 (Eylül 2025) — EN GÜNCEL LTS SÜRÜMÜ
> Bu klasör, Java-Versiyon-Analizi serisinin en detaylı bölümüdür. > Çünkü Java 25, şu an piyasadaki en güncel LTS (Long-Term Support) sürümüdür > ve 2026 itibarıyla kurumsal projelerin birincil hedef sürümüdür.
Java 25 (Eylül 2025) — EN GÜNCEL LTS SÜRÜMÜ
Bu klasör,
Java-Versiyon-Analiziserisinin en detaylı bölümüdür. Çünkü Java 25, şu an piyasadaki en güncel LTS (Long-Term Support) sürümüdür ve 2026 itibarıyla kurumsal projelerin birincil hedef sürümüdür.
1. Sürüm Bilgisi
| Özellik | Değer |
|---|---|
| Sürüm | Java 25 (JDK 25) |
| Çıkış tarihi | Eylül 2025 |
| Destek tipi | LTS (Long-Term Support) |
| Bir önceki LTS | Java 21 (Eylül 2023) |
| Ondan önceki LTS | Java 17 (Eylül 2021) |
| Sürüm kadansı | Her 6 ayda bir feature release, her 2 yılda bir LTS |
Not (dürüstlük): JEP numaralarını ve hangi özelliğin kalıcı/preview olduğunu mümkün olduğunca doğru verdim. Emin olmadığım kesin imzalar/sayısal detaylarda genel kaldım ve "resmi JEP'e bakın" notu düştüm. Uydurma yapmadım.
2. LTS NEDEN BU KADAR ÖNEMLİ? (GÜÇLÜ VURGU)
LTS Nedir?
LTS = Long-Term Support (Uzun Süreli Destek). Oracle ve OpenJDK ekosistemi, sürümleri her 6 ayda bir yayınlar. Ancak bu sürümlerin çoğu yalnızca 6 ay güncelleme alır (feature release / non-LTS). LTS sürümleri ise yıllarca (genellikle 8+ yıl, dağıtıcıya göre değişir) güvenlik yamaları ve hata düzeltmeleri alır.
Kurumsallar Neden LTS Bekler?
Bir non-LTS sürüm (örn. Java 22, 23, 24) çıktığında, kurumsal şirketler genelde onları production'a almaz. Bunun nedenleri:
- Uzun destek penceresi: Bir bankanın çekirdek sistemini her 6 ayda bir yeni JDK'ya taşıması imkânsızdır. LTS, "kur ve yıllarca güvenle kullan" demektir.
- Güvenlik güncellemeleri: LTS dışı bir sürüm 6 ay sonra güncelleme almaz; yeni keşfedilen güvenlik açıkları (CVE) yamalanmaz. Bu, kurumsal için kabul edilemez.
- Kararlılık (stability): LTS sürümlerinde özellikler oturmuş, preview'lar kalıcılaşmış, ekosistem (kütüphaneler, framework'ler, araçlar) uyum sağlamıştır.
- Uyumluluk & sertifikasyon: Spring, Jakarta EE, uygulama sunucuları (Tomcat, WildFly), build araçları (Maven, Gradle) ve bulut sağlayıcıları desteklerini önce LTS sürümlere verir.
- Maliyet & risk yönetimi: Sık yükseltme = sürekli test/regresyon maliyeti. LTS, yükseltme döngüsünü 2–3 yıla yayarak riski ve maliyeti düşürür.
Java 25 = Yeni Kurumsal Hedef
- Java 8 uzun yıllar fiili standarttı (hâlâ çok yaygın).
- Java 11 ilk modern LTS olarak benimsendi.
- Java 17 "modern Java"ya geçişin omurgası oldu (records, sealed, pattern matching).
- Java 21 sanal thread'ler (virtual threads) ile devrim yaptı.
- Java 25 ise bu birikimi olgunlaştırarak kalıcı hale getirdi: Scoped Values, Flexible Constructor Bodies, Compact Source Files, Module Import Declarations gibi özellikler artık preview değil, standart.
Sonuç: 2026'da yeni bir kurumsal proje başlatıyorsanız ya da mevcut bir sistemi yükseltiyorsanız hedef sürüm Java 25 olmalıdır. Java 17 veya 21'de kalan ekipler için 25, "bir sonraki güvenli durak"tır.
3. Genel Bakış — Java 25 Neler Getirdi?
Java 25 hem kalıcılaşan hem de hâlâ preview olan özellikler içerir. Aşağıdaki tablo durumu dürüstçe özetler:
| Özellik | JEP | Durum (Java 25) | Örnek Dosya |
|---|---|---|---|
| Compact Source Files & Instance Main | 512 | KALICI | CompactSourceMainMethods.java |
| Scoped Values | 506 | KALICI | ScopedValuesKalici.java |
| Flexible Constructor Bodies | 513 | KALICI | FlexibleConstructorBodies.java |
| Module Import Declarations | 511 | KALICI | (README) |
| Stable Values | 502 | PREVIEW | StableValuesPreview.java |
| Structured Concurrency | 505 | PREVIEW (5.) | StructuredConcurrencyGuncel.java |
| PEM Encodings of Crypto Objects | 470 | PREVIEW | (README) |
| Primitive Types in Patterns/instanceof/switch | 507 | PREVIEW (devam) | (README) |
| Compact Object Headers | 519 | Ürün özelliği (JVM) | (README) |
| Generational Shenandoah | — | İyileştirme (JVM) | (README) |
4. Özellik Detayları
Her özellik için: NEDİR / NEDEN GELDİ / NE İŞE YARAR / NEREDE KOLAYLIK SAĞLAR / ESKİ vs YENİ / GERÇEK HAYAT.
4.1. Compact Source Files & Instance Main Methods — KALICI (JEP 512)
Dosya: CompactSourceMainMethods.java
- NEDİR: Bir
.javadosyasını sınıf bildirimi (public class ...) olmadan, doğrudanvoid main()ile yazabilme.mainartıkstatic,publicveString[] argszorunlu değil. AyrıcaIO.println(...)/IO.readln(...)otomatik kullanılabilir. - NEDEN GELDİ: Yeni başlayanların "Merhaba Dünya" yazmak için
public,static,void,String[] argsveclasskavramlarını aynı anda öğrenme bariyerini kaldırmak. Java'yı öğrenmeye giriş kolaylaştırılır. - NE İŞE YARAR: Kavramların kademeli öğretilmesini sağlar; küçük script/araçlar için boilerplate'i azaltır.
- NEREDE KOLAYLIK: Eğitim, prototipleme, tek dosyalık yardımcı programlar.
- ESKİ vs YENİ:
// ESKİ (Java 1.0–24) public class Merhaba { public static void main(String[] args) { System.out.println("Merhaba Dünya"); } } // YENİ (Java 25 - KALICI) void main() { IO.println("Merhaba Dünya"); } - GERÇEK HAYAT: Bir öğrenci ilk günden tek satır kodla girdi/çıktı yapabilir;
bir DevOps mühendisi
java arac.javaile hızlı bir bakım scripti çalıştırabilir. - Tarih (dürüst): Java 21 → 24 arasında 4 farklı preview adından geçti
(Unnamed Classes → Implicitly Declared → Simple Source → Compact Source).
Java 25'te nihayet kalıcı oldu,
--enable-previewgerekmez.
4.2. Scoped Values — KALICI (JEP 506)
Dosya: ScopedValuesKalici.java
- NEDİR:
ScopedValue<T>, bir thread ve onun alt görevleri boyunca değişmez bir bağlam değeri taşımanın modern yolu.ThreadLocal'a alternatiftir. - NEDEN GELDİ:
ThreadLocaldeğiştirilebilir (mutable),remove()unutulursa thread havuzlarında bellek sızıntısına yol açar ve milyonlarca sanal thread ile pahalıdır. Scoped Values bu sorunları çözer. - NE İŞE YARAR: İstek (request) bağlamı, kullanıcı kimliği, korelasyon ID'si, dil/lokal bilgisi gibi verileri parametre zinciri olmadan alt katmanlara taşır.
- NEREDE KOLAYLIK: Web sunucuları, mikroservis çağrı zincirleri, loglama bağlamı (MDC benzeri), güvenlik bağlamı.
- ESKİ vs YENİ:
// ESKİ: ThreadLocal (mutable, remove() unutulursa sızıntı) static final ThreadLocal<Kullanici> TL = new ThreadLocal<>(); TL.set(kullanici); try { ... } finally { TL.remove(); } // YENİ: ScopedValue (immutable, otomatik temizlik, sanal thread dostu) ScopedValue.where(AKTIF_KULLANICI, kullanici).run(() -> { ... }); - GERÇEK HAYAT: Bir HTTP isteği geldiğinde kullanıcı + istek ID'si bağlama konur; servis ve veri erişim katmanları bu değerleri parametre taşımadan okur. Blok bittiğinde değer otomatik geçersizleşir.
4.3. Flexible Constructor Bodies — KALICI (JEP 513)
Dosya: FlexibleConstructorBodies.java
- NEDİR:
super(...)veyathis(...)çağrısından önce ifade çalıştırabilme (alan doğrulama, ön hesaplama). Kısıt: bu çağrıdan öncethis'in alanlarına/metotlarına erişilemez. - NEDEN GELDİ: Eskiden
super(...)ilk satır olmak zorundaydı; doğrulama yapmak için statik yardımcı metot hilesi gerekiyordu. - NE İŞE YARAR: Argüman doğrulama, dönüşüm, ön hesaplama yapılmasını doğal ve okunabilir kılar.
- NEREDE KOLAYLIK: Değer nesneleri (value objects), domain modelleri, immutable sınıflar.
- ESKİ vs YENİ:
// ESKİ: static metot hilesi public Calisan(String ad, int maas) { super(dogrula(maas)); // hile this.ad = ad; } private static int dogrula(int m) { if (m<0) throw ...; return m; } // YENİ (Java 25 - KALICI) public Calisan(String ad, int maas) { if (maas < 0) throw new IllegalArgumentException("..."); super(maas); // doğrudan this.ad = ad; } - GERÇEK HAYAT:
Cember(double yaricap)→ alanısuper'a göndermeden önce hesaplar;Dikdortgen(double kenar)→this(kenar, kenar)çağrısından önce doğrulama yapar.
4.4. Module Import Declarations — KALICI (JEP 511)
(README)
- NEDİR:
import module M;ile bir modülün dışa açtığı tüm paketleri tek satırda import edebilme. - NEDEN GELDİ: Çok sayıda tekil
importsatırını azaltmak; özellikle eğitim ve hızlı kod yazımında kolaylık. - ESKİ vs YENİ:
// ESKİ import java.util.List; import java.util.Map; import java.util.stream.Collectors; // YENİ import module java.base; // java.base modülünün açtığı tüm paketler - NEREDE KOLAYLIK: Compact source dosyaları + module import birlikte, Java'ya girişi ciddi şekilde sadeleştirir. Büyük projelerde tekil import'lar hâlâ tercih edilebilir (açıklık için).
4.5. Stable Values — PREVIEW (JEP 502)
Dosya: StableValuesPreview.java — --enable-preview gerekir.
- NEDİR:
StableValue<T>, en fazla bir kez atanan, sonra değişmez olan bir tutucu. Lazy (tembel) başlatma için tasarlanmış. - NEDEN GELDİ:
finalalanlar hemen atanmak zorundadır (lazy olamaz). Lazy yapmak için tarihsel olarak hatalı double-checked locking kullanılırdı. StableValue, "final'ın performansı + lazy'nin esnekliği" sunar; JIT atandıktan sonra değeri sabit gibi optimize edebilir (constant folding). - ESKİ vs YENİ:
// ESKİ: double-checked locking (hataya açık, uzun) private volatile Agir n; Agir get() { if (n==null) synchronized(this){ if(n==null) n=new Agir(); } return n; } // YENİ (PREVIEW): tek satır, güvenli private final StableValue<Agir> n = StableValue.of(); Agir get() { return n.orElseSet(() -> new Agir()); } - GERÇEK HAYAT: Pahalı bir veritabanı bağlantı dizesini/önbelleğini yalnızca ilk ihtiyaçta bir kez hesaplayıp cache'lemek.
- DÜRÜSTLÜK NOTU: PREVIEW olduğu için API isimleri (
of,orElseSet) sürümler arası değişebilir; resmi JEP 502'ye bakın.
4.6. Structured Concurrency — HÂLÂ PREVIEW (JEP 505)
Dosya: StructuredConcurrencyGuncel.java — --enable-preview gerekir.
- DÜRÜSTLÜK NOTU: Bu özellik Java 25'te kalıcı DEĞİL, hâlâ preview
(5. tur). API son turlarda değişti (eski
ShutdownOnFailureyerineStructuredTaskScope.open(...)+Joiner). - NEDİR: Aynı mantıksal işi yapan birden çok eş zamanlı alt görevi tek bir birim gibi ele alma. Bir görev başarısız olursa diğerleri otomatik iptal edilir.
- NEDEN GELDİ:
ExecutorService+Futureile iptal yayılımı elle yapılır, thread sızıntısı riski vardır, hata yönetimi dağınıktır. - NE İŞE YARAR: Birden çok servisten paralel veri çekme, hata yayılımı, iptal, zaman aşımı yönetimini yapısal ve okunabilir kılar.
- ESKİ vs YENİ:
// ESKİ (yapısız): f1 patlarsa f2 iptal edilmez Future<A> f1 = ex.submit(...); Future<B> f2 = ex.submit(...); // YENİ (PREVIEW): biri patlarsa diğeri otomatik iptal try (var scope = StructuredTaskScope.open(...)) { var t1 = scope.fork(() -> servisA()); var t2 = scope.fork(() -> servisB()); scope.join(); return birlestir(t1.get(), t2.get()); } - GERÇEK HAYAT: Bir kullanıcı profilini oluşturmak için "temel bilgi" ve "sipariş özeti" servislerini paralel çağırıp birleştirme; biri 503 dönerse diğeri iptal edilir, hata yukarı yayılır.
4.7. PEM Encodings of Cryptographic Objects — PREVIEW (JEP 470)
(README)
- NEDİR: Kriptografik nesnelerin (anahtarlar, sertifikalar) PEM (Base64,
-----BEGIN ...-----bloklu) metin formatında kodlanması/çözülmesi için standart API. - NEDEN GELDİ: Eskiden PEM ile çalışmak için elle Base64 + sınır satırı işleme ya da üçüncü parti kütüphane (örn. BouncyCastle) gerekiyordu.
- DÜRÜSTLÜK NOTU: PREVIEW. TLS sertifikaları, SSH anahtarları gibi yaygın formatlarla çalışan güvenlik kodları için kolaylık hedefler.
4.8. Primitive Types in Patterns, instanceof, switch — PREVIEW (devam)
(README)
- NEDİR:
instanceofveswitchpattern matching'in ilkel tipleri (int, long, double...) de desteklemesi. - NEDEN GELDİ: Pattern matching'i yalnızca referans tiplerle sınırlı bırakmamak; sayısal aralık/dönüşüm kontrollerini daha güvenli yazmak.
- DÜRÜSTLÜK NOTU: Hâlâ PREVIEW. Örnek:
if (x instanceof int i) { ... } // PREVIEW switch (deger) { case int i -> ...; case double d -> ...; }
4.9. JVM / Performans İyileştirmeleri (genel)
(README)
- Compact Object Headers (JEP 519): Nesne başlıklarını küçülterek heap kullanımını azaltır; bellek tasarrufu ve daha iyi cache davranışı sağlar. (Java 24'te deneysel/JEP 450 idi, 25'te ürün özelliği olarak olgunlaştı.)
- Generational GC iyileştirmeleri: Shenandoah'ın generational varyantı gibi çöp toplayıcı iyileştirmeleri, düşük gecikmeli (low-latency) iş yükleri için.
- Sanal thread olgunlaşması: Java 21'de kalıcılaşan virtual threads, Scoped Values + Structured Concurrency ile birlikte daha güçlü bir eşzamanlılık modeli oluşturur.
Dürüstlük: Performans JEP'lerinin kesin sayısal kazanımları iş yüküne bağlıdır; genel kaldım, somut yüzde vaadi vermedim.
5. Önceki Preview Özellikler Nasıl Olgunlaştı? (Olgunlaşma Tablosu)
Modern Java'nın felsefesi: özellikler preview → kalıcı yolculuğundan geçer. Java 25, bu olgunlaşmanın çoğunu tamamladığı için bir LTS "toplama noktası"dır.
| Özellik | Önce | Java 25'teki durum |
|---|---|---|
| Records | Java 14 preview | Kalıcı (16'dan beri) — yaygın |
| Sealed Classes | Java 15 preview | Kalıcı (17) |
| Pattern Matching (switch) | Java 17 preview | Kalıcı (21) |
| Sanal Thread'ler | Java 19 preview | Kalıcı (21) |
| Sequenced Collections | Java 21 | Kalıcı (21) |
| Stream Gatherers | Java 22 preview | Kalıcı (24) |
| Foreign Function & Memory (FFM) | uzun preview | Kalıcı (22) |
| Scoped Values | Java 20 incubator | Kalıcı (25, JEP 506) |
| Flexible Constructor Bodies | Java 22 preview | Kalıcı (25, JEP 513) |
| Compact Source & Instance Main | Java 21 preview | Kalıcı (25, JEP 512) |
| Module Import Declarations | Java 23 preview | Kalıcı (25, JEP 511) |
| Structured Concurrency | Java 19 incubator | HÂLÂ preview (25, JEP 505) |
| Stable Values | Java 25 | preview (JEP 502) |
| String Templates | Java 21–22 preview | GERİ ÇEKİLDİ — DİKKAT (aşağıda) |
String Templates — DÜRÜST UYARI
- String Templates (
STR."...") Java 21 ve 22'de preview olarak geldi. - Java 23'te tasarım sorunları nedeniyle GERİ ÇEKİLDİ (kaldırıldı).
- Java 25'te String Templates YOKTUR. Bu önemli bir derstir: her preview özellik kalıcılaşmaz; bazıları tamamen iptal olabilir.
- Bugün string birleştirme için hâlâ
+,String.format(...),StringBuilderveyaMessageFormatkullanılır.
Çıkarım: Preview özelliklere production'da bel bağlamayın. LTS'in değeri tam da burada: 25'te kalıcı olanlar, "geri çekilme riski" geçmiş özelliklerdir.
6. Geçiş Rehberi: Java 17 / 21 → Java 25
17 → 25 (büyük sıçrama)
17 ile 25 arasında çok şey değişti. Dikkat edilecekler:
- Sanal thread'ler (21): I/O ağırlıklı sunucularda thread havuzu modelini yeniden değerlendirin.
- Deprecate/kaldırılanlar:
sun.misc.Unsafe'in bazı bellek metotları, eski güvenlik yöneticisi (Security Manager) gibi unsurlar kullanım dışı bırakıldı. Üçüncü parti kütüphanelerinizin uyumunu kontrol edin. - Kapsüllenmiş JDK içi API'ler: Güçlü kapsülleme (strong encapsulation)
nedeniyle
--add-opensile zorlayan kütüphaneler kırılabilir. - Build araçları: Maven/Gradle, derleyici eklentilerini ve hedef sürümü
(
--release 25) güncelleyin.
21 → 25 (daha yumuşak)
21 zaten modern bir temel olduğu için geçiş görece kolaydır:
- Yeni kalıcı özellikleri benimseyin: Scoped Values (ThreadLocal yerine), Flexible Constructor Bodies, Module Import.
- Preview kullanıyorsanız: Bazı 21 preview'ları 25'te kalıcılaştı; kodunuzdan
--enable-previewbayraklarını kaldırmanız gerekebilir. - String Templates kullandıysanız: 23'te kaldırıldığı için kodunuzu
String.format/+'a geri çevirmeniz gerekir.
Genel Geçiş Adımları
- Bağımlılıkları (Spring Boot 3.x+, vb.) Java 25 destekleyen sürümlere yükseltin.
--release 25ile derleyin, derleme uyarılarını giderin.- Test paketini (unit + entegrasyon) çalıştırın; GC log'larını gözlemleyin.
- Staging ortamında performans/regresyon testi yapın.
- Kademeli (canary) dağıtımla production'a alın.
7. Avantaj / Dezavantaj / Risk
Avantajlar
- LTS: Yıllarca güvenlik ve hata düzeltmesi → kurumsal güven.
- Olgunlaşmış özellikler: Scoped Values, Flexible Constructors, Compact Source artık kalıcı; preview riski yok.
- Performans/bellek: Compact Object Headers, GC iyileştirmeleri.
- Modern eşzamanlılık: Virtual threads + Scoped Values güçlü kombinasyon.
- Öğrenme kolaylığı: Compact source + module import + IO.
Dezavantajlar / Riskler
- Hâlâ preview olanlar: Structured Concurrency ve Stable Values kalıcı değil; production'da bel bağlamak risklidir, API değişebilir.
- Kaldırılan API'ler: Eski güvenlik yöneticisi, bazı Unsafe metotları → eski kütüphaneler kırılabilir.
- 17'den büyük sıçrama: Test/regresyon maliyeti; bağımlılık uyumu.
- String Templates yok: 23'te kaldırıldı; ona bel bağlamış kod taşınamaz.
8. Dosya Referansları (bu klasör)
| Dosya | Konu | Derleme notu |
|---|---|---|
README.md | Bu doküman | — |
CompactSourceMainMethods.java | Compact source & instance main (KALICI) | javac / java (preview gerekmez) |
ScopedValuesKalici.java | Scoped Values (KALICI) | javac / java (preview gerekmez) |
FlexibleConstructorBodies.java | Esnek constructor (KALICI) | javac / java (preview gerekmez) |
StableValuesPreview.java | Stable Values (PREVIEW) | javac --release 25 --enable-preview ... |
StructuredConcurrencyGuncel.java | Structured Concurrency (PREVIEW) | javac --release 25 --enable-preview ... |
Hızlı Çalıştırma
# Kalıcı özellikler (preview bayrağı gerekmez) javac CompactSourceMainMethods.java && java CompactSourceMainMethods javac ScopedValuesKalici.java && java ScopedValuesKalici javac FlexibleConstructorBodies.java && java FlexibleConstructorBodies # Preview özellikler (--enable-preview ZORUNLU) javac --release 25 --enable-preview StableValuesPreview.java java --enable-preview StableValuesPreview javac --release 25 --enable-preview StructuredConcurrencyGuncel.java java --enable-preview StructuredConcurrencyGuncel
9. Özet — Neden Java 25?
Java 25, modern Java'nın yıllardır biriken yeniliklerini kalıcılaştıran, uzun süre destek alacak ve ekosistemin etrafında toplanacağı en güncel LTS sürümüdür. 2026'da yeni proje başlatan ya da 17/21'den yükselten her ekip için varsayılan hedef budur. Preview özelliklerin (Structured Concurrency, Stable Values) henüz olgunlaşmadığını ve String Templates'in geri çekildiğini unutmadan, kalıcı özellikleri gönül rahatlığıyla kullanabilirsiniz.
▶ Kod Örnekleri(5)
CompactSourceMainMethods
çalıştırılabilir1// ============================================================================
2// Java 25 - Compact Source Files & Instance Main Methods (JEP 512 - KALICI)
3// ============================================================================
4// Bu dosya, Java 25 ile birlikte KALICI (final/standard) hale gelen
5// "Compact Source Files" ve "Instance Main Methods" ozelligini anlatir.
6//
7// ONEMLI TARIHCE (DURUST OZET):
8// - Java 21 (JEP 445): "Unnamed Classes and Instance Main Methods" (preview)
9// - Java 22 (JEP 463): "Implicitly Declared Classes..." (2. preview)
10// - Java 23 (JEP 477): "Implicitly Declared Classes and Instance Main
11// Methods" (3. preview) + otomatik java.io importlari
12// - Java 24 (JEP 495): "Simple Source Files and Instance Main Methods"
13// (4. preview)
14// - Java 25 (JEP 512): "Compact Source Files and Instance Main Methods"
15// -> NIHAYET KALICI! Artik --enable-preview gerekmez.
16//
17// Bu dosyanin KENDISI klasik bir sinif icinde main barindirir, cunku bir
18// ".java" dosyasinda hem aciklama yapip hem de "compact" sentaksini ayni
19// dosyada gostermek istiyoruz. Compact source ornekleri YORUM olarak
20// asagida sunulmustur; ayrica calistirilabilir bir karsilastirma da var.
21// ============================================================================
22
23public class CompactSourceMainMethods {
24
25 // ------------------------------------------------------------------------
26 // 1) KLASIK (Java 1.0 - 24) YONTEM
27 // ------------------------------------------------------------------------
28 // Yeni baslayan biri "Merhaba Dunya" yazmak icin sunlari OGRENMEK zorundaydi:
29 // - "public" niye var? (erisim belirleyici)
30 // - "static" niye var? (nesne olmadan cagrilabilirlik)
31 // - "void" niye var? (donus tipi)
32 // - "String[] args" niye var? (komut satiri argumanlari)
33 // - "class" sarmali niye var? (her seyin bir sinifta olmasi)
34 // Bu 5 kavram, ilk satir kodu yazmadan once kafa karistirir.
35 //
36 // Klasik hali:
37 //
38 // public class Merhaba {
39 // public static void main(String[] args) {
40 // System.out.println("Merhaba Dunya");
41 // }
42 // }
43
44 public static void main(String[] args) {
45 System.out.println("=== Java 25: Compact Source & Instance Main ===\n");
46
47 klasikYontemAciklama();
48 yeniYontemAciklama();
49 otomatikImportAciklama();
50 ogrenmeEgrisiKarsilastirmasi();
51
52 System.out.println("\n--- Calistirilabilir mini gosterim ---");
53 // Asagidaki instance-stili metodu, klasik dosyada normal bir nesne
54 // uretip cagirarak "instance main" mantigini simule ediyoruz.
55 CompactSourceMainMethods uygulama = new CompactSourceMainMethods();
56 uygulama.calis();
57 }
58
59 // ------------------------------------------------------------------------
60 // 2) YENI (Java 25, JEP 512) YONTEM - COMPACT SOURCE FILE
61 // ------------------------------------------------------------------------
62 static void yeniYontemAciklama() {
63 System.out.println(">> YENI YONTEM (Java 25 - KALICI):");
64 System.out.println(" Bir .java dosyasinin tamami su kadar olabilir:\n");
65 System.out.println(" void main() {");
66 System.out.println(" IO.println(\"Merhaba Dunya\");");
67 System.out.println(" }\n");
68 System.out.println(" Aciklama:");
69 System.out.println(" - 'class' bildirimi YOK -> derleyici gizli (compact) bir");
70 System.out.println(" sinif olusturur. Buna 'compact source file' denir.");
71 System.out.println(" - main artik 'static' OLMAK ZORUNDA DEGIL -> instance main.");
72 System.out.println(" - 'String[] args' parametresi ZORUNLU DEGIL -> argumansiz main.");
73 System.out.println(" - 'public' belirleyicisi ZORUNLU DEGIL.");
74 System.out.println(" - IO.println(...) otomatik kullanilabilir (java.io.IO).\n");
75 }
76
77 static void klasikYontemAciklama() {
78 System.out.println(">> KLASIK YONTEM (Java 1.0 - 24):");
79 System.out.println(" public class Merhaba {");
80 System.out.println(" public static void main(String[] args) {");
81 System.out.println(" System.out.println(\"Merhaba Dunya\");");
82 System.out.println(" }");
83 System.out.println(" }");
84 System.out.println(" -> Yeni baslayan 5 farkli kavrami ayni anda ogrenmek zorunda.\n");
85 }
86
87 // ------------------------------------------------------------------------
88 // 3) OTOMATIK IMPORT EDILEN IO
89 // ------------------------------------------------------------------------
90 static void otomatikImportAciklama() {
91 System.out.println(">> OTOMATIK IO (java.io.IO):");
92 System.out.println(" Compact source dosyalarinda asagidaki gibi kisa metotlar");
93 System.out.println(" otomatik kullanilabilir (ek import gerekmeden):");
94 System.out.println(" IO.println(\"...\"); // ekrana yazar");
95 System.out.println(" IO.print(\"...\"); // satir sonu eklemeden yazar");
96 System.out.println(" String ad = IO.readln(\"Adiniz: \"); // kullanicidan okur");
97 System.out.println(" Bu sayede System.out.println / Scanner ezberi ilk gunden");
98 System.out.println(" gerekmez; ogrenci hizlica girdi-cikti yapabilir.\n");
99 }
100
101 // ------------------------------------------------------------------------
102 // 4) OGRENME EGRISI KARSILASTIRMASI
103 // ------------------------------------------------------------------------
104 static void ogrenmeEgrisiKarsilastirmasi() {
105 System.out.println(">> NEDEN GELDI / NE ISE YARAR:");
106 System.out.println(" - Egitimde 'ilk program' bariyerini dusurur.");
107 System.out.println(" - Kavramlari ASAMALI ogretmeyi mumkun kilar:");
108 System.out.println(" Asama 1: void main() { ... } (en sade)");
109 System.out.println(" Asama 2: void main(String[] args) (argumanlar)");
110 System.out.println(" Asama 3: static void main(...) (statiklik)");
111 System.out.println(" Asama 4: public class ... { ... } (sinif/erisim)");
112 System.out.println(" - Kurumsal kodda da kucuk script/araclar icin sadelik saglar.");
113 System.out.println(" - DIKKAT: Buyuk projelerde hala klasik sinif yapisi kullanilir;");
114 System.out.println(" bu ozellik onu YOK ETMEZ, alternatif/giris yolu sunar.\n");
115 }
116
117 // ------------------------------------------------------------------------
118 // Instance main mantigini simule eden ornek (klasik dosyada nesne ile)
119 // ------------------------------------------------------------------------
120 void calis() {
121 // Java 25'te compact source dosyasinda bu metot dogrudan 'void main()'
122 // olarak yazilabilir ve nesneyi JVM kendisi olusturur.
123 System.out.println("Instance metot calisti (compact source'ta 'void main()' olurdu).");
124 }
125}
126
127/*
128 ============================================================================
129 GERCEK COMPACT SOURCE ORNEGI (ayri bir dosyaya kopyalanarak denenebilir)
130 ============================================================================
131 Asagidaki icerigi "Selam.java" adli AYRI bir dosyaya yazip
132 Java 25 ile soyle calistirabilirsiniz:
133
134 java Selam.java (kaynak dosyasini dogrudan calistirma)
135
136 --- Selam.java icerigi (compact source - Java 25) ---
137
138 void main() {
139 IO.println("Merhaba Dunya - Compact Source!");
140 String ad = IO.readln("Adiniz nedir? ");
141 IO.println("Hos geldin, " + ad + "!");
142 }
143
144 --- BU ORNEK NIYE ONEMLI ---
145 - Toplam 4 satir. 'class', 'public', 'static', 'String[] args',
146 'System.out', 'import' YOK.
147 - Java 25'te KALICI oldugu icin --enable-preview GEREKMEZ.
148
149 NOT (DURUSTLUK): Compact source dosyasinda alanlar ve baska metotlar da
150 tanimlanabilir; bunlar gizli sinifin uyeleri olur. Birden fazla
151 "compact" dosyayi normal sekilde import edip kullanmak ise klasik
152 modulariteyi gerektirir.
153 ============================================================================
154*/FlexibleConstructorBodies
ortam gerekir1// ============================================================================
2// Java 25 - Flexible Constructor Bodies (JEP 513 - KALICI)
3// ============================================================================
4// Flexible Constructor Bodies, Java 25 ile birlikte KALICI (standart) oldu.
5// Artik --enable-preview gerekmez.
6//
7// TARIHCE (DURUST OZET):
8// - Java 22 (JEP 447): Statements before super(...) (preview)
9// - Java 23 (JEP 482): Flexible Constructor Bodies (2. preview)
10// - Java 24 (JEP 492): Flexible Constructor Bodies (3. preview)
11// - Java 25 (JEP 513): KALICI (standard)
12//
13// NEDIR:
14// Eskiden bir yapilandiricida (constructor) super(...) veya this(...)
15// cagrisi MUTLAKA ilk satir olmak zorundaydi. Artik bu cagridan ONCE
16// "prologue" (on bolum) adi verilen ifadeler calistirilabilir:
17// - alan dogrulama (validation)
18// - argumanlar uzerinde on hesaplama / donusum
19// - super'a gonderilecek degeri hazirlama
20// KISIT: super()/this() cagrisindan ONCE, henuz olusmakta olan nesnenin
21// alanlarina/metotlarina ERISILEMEZ (this hala tam kurulmadi).
22//
23// DERLEME / CALISTIRMA (Java 25):
24// javac FlexibleConstructorBodies.java
25// java FlexibleConstructorBodies
26// ============================================================================
27
28public class FlexibleConstructorBodies {
29
30 public static void main(String[] args) {
31 System.out.println("=== Java 25: Flexible Constructor Bodies (KALICI) ===\n");
32
33 eskiVsYeniAciklama();
34
35 System.out.println("\n--- 1) Alan dogrulama (super'dan ONCE) ---");
36 try {
37 new Calisan("Ahmet", -5000); // gecersiz maas -> super'a gitmeden hata
38 } catch (IllegalArgumentException e) {
39 System.out.println("Beklenen hata: " + e.getMessage());
40 }
41 Calisan c = new Calisan("Zeynep", 45000);
42 System.out.println("Olusturuldu: " + c);
43
44 System.out.println("\n--- 2) On hesaplama / donusum (super'dan ONCE) ---");
45 Cember cember = new Cember(2.0);
46 System.out.println("Cember -> " + cember);
47
48 System.out.println("\n--- 3) this(...) oncesi calismayla varsayilan uretme ---");
49 Dikdortgen kare = new Dikdortgen(5.0); // tek argumanli -> kare
50 Dikdortgen dik = new Dikdortgen(3.0, 4.0);
51 System.out.println("Kare -> " + kare);
52 System.out.println("Dikdortgen -> " + dik);
53 }
54
55 static void eskiVsYeniAciklama() {
56 System.out.println(">> ESKI YONTEM (Java 24 ve oncesi):");
57 System.out.println(" super(...) ILK satir olmak zorundaydi. Dogrulama yapmak icin");
58 System.out.println(" genelde STATIK YARDIMCI METOT hilesine basvurulurdu:\n");
59 System.out.println(" public Calisan(String ad, int maas) {");
60 System.out.println(" super(dogrula(maas)); // hile: static metot ile dogrula");
61 System.out.println(" this.ad = ad;");
62 System.out.println(" }");
63 System.out.println(" private static int dogrula(int m) {");
64 System.out.println(" if (m < 0) throw new IllegalArgumentException(...);");
65 System.out.println(" return m;");
66 System.out.println(" }\n");
67 System.out.println(">> YENI YONTEM (Java 25 - KALICI):");
68 System.out.println(" public Calisan(String ad, int maas) {");
69 System.out.println(" if (maas < 0) // super'dan ONCE!");
70 System.out.println(" throw new IllegalArgumentException(...);");
71 System.out.println(" super(maas); // dogrudan, hile yok");
72 System.out.println(" this.ad = ad;");
73 System.out.println(" }");
74 System.out.println(" -> Daha okunabilir, ekstra static metot YOK, niyet acik.\n");
75 }
76}
77
78// ----------------------------------------------------------------------------
79// Ust sinif: bir maas alanini tutar.
80// ----------------------------------------------------------------------------
81class Personel {
82 protected final int maas;
83 Personel(int maas) {
84 this.maas = maas;
85 }
86}
87
88// ----------------------------------------------------------------------------
89// 1) ALAN DOGRULAMA: super(...) cagrisindan ONCE dogrulama yapiyoruz.
90// Yeni Java 25 ile bu tamamen yasal ve okunabilir.
91// ----------------------------------------------------------------------------
92class Calisan extends Personel {
93 private final String ad;
94
95 Calisan(String ad, int maas) {
96 // super(...) cagrisindan ONCE calisan ifadeler (prologue):
97 if (ad == null || ad.isBlank()) {
98 throw new IllegalArgumentException("Ad bos olamaz");
99 }
100 if (maas < 0) {
101 throw new IllegalArgumentException("Maas negatif olamaz: " + maas);
102 }
103 // Dogrulama gectikten sonra ust yapilandiriciyi cagiriyoruz:
104 super(maas);
105 // super()'dan SONRA artik this'e erisebiliriz:
106 this.ad = ad;
107 }
108
109 @Override
110 public String toString() {
111 return "Calisan{ad='" + ad + "', maas=" + maas + "}";
112 }
113}
114
115// ----------------------------------------------------------------------------
116// 2) ON HESAPLAMA: super'a gonderilecek degeri, cagri oncesinde hesapliyoruz.
117// ----------------------------------------------------------------------------
118class Sekil {
119 protected final double alan;
120 Sekil(double alan) {
121 this.alan = alan;
122 }
123}
124
125class Cember extends Sekil {
126 private final double yaricap;
127
128 Cember(double yaricap) {
129 // Yaricaptan alani super'a gondermeden ONCE hesapliyoruz.
130 if (yaricap <= 0) {
131 throw new IllegalArgumentException("Yaricap pozitif olmali");
132 }
133 double hesaplananAlan = Math.PI * yaricap * yaricap;
134 super(hesaplananAlan);
135 this.yaricap = yaricap;
136 }
137
138 @Override
139 public String toString() {
140 return String.format("Cember{yaricap=%.1f, alan=%.4f}", yaricap, alan);
141 }
142}
143
144// ----------------------------------------------------------------------------
145// 3) this(...) ONCESI calisma: argumanlardan varsayilan turetip
146// baska yapilandiriciya yonlendirme.
147// ----------------------------------------------------------------------------
148class Dikdortgen {
149 final double en;
150 final double boy;
151
152 // Asil yapilandirici
153 Dikdortgen(double en, double boy) {
154 this.en = en;
155 this.boy = boy;
156 }
157
158 // Tek argumanli: kare olusturmak icin. this(...) ONCESI dogrulama yapiyoruz.
159 Dikdortgen(double kenar) {
160 if (kenar <= 0) {
161 throw new IllegalArgumentException("Kenar pozitif olmali");
162 }
163 // this(...) cagrisindan once ifade calistirabiliyoruz (Java 25).
164 this(kenar, kenar);
165 }
166
167 @Override
168 public String toString() {
169 return String.format("Dikdortgen{en=%.1f, boy=%.1f, alan=%.1f}", en, boy, en * boy);
170 }
171}Bu sürüm-analizi örneği tek dosya olarak yerel JDK 21 ile çalıştırılamadı (bağımsız bir main içermeyebilir ya da daha yeni bir JDK / önizleme özelliği gerektirir). İlgili dil özelliği yukarıdaki anlatım ve kodda gösterilmiştir.
ScopedValuesKalici
ortam gerekir1// ============================================================================
2// Java 25 - Scoped Values (JEP 506 - KALICI)
3// ============================================================================
4// Scoped Values, Java 25 ile birlikte KALICI (standart) hale geldi.
5// Artik --enable-preview gerekmez.
6//
7// TARIHCE (DURUST OZET):
8// - Java 20 (JEP 429): Scoped Values (incubator)
9// - Java 21 (JEP 446): preview
10// - Java 22 (JEP 464): 2. preview
11// - Java 23 (JEP 481): 3. preview
12// - Java 24 (JEP 487): 4. preview
13// - Java 25 (JEP 506): KALICI (standard)
14//
15// NEDIR:
16// ScopedValue<T>, bir is parcacigi (thread) ve onun olusturdugu alt
17// gorevler boyunca DEGISMEZ (immutable) bir baglam degeri tasimanin
18// modern, guvenli yoludur. ThreadLocal'in yerine gecen, sanal thread
19// (virtual thread) dostu bir alternatiftir.
20//
21// DERLEME / CALISTIRMA (Java 25):
22// javac ScopedValuesKalici.java
23// java ScopedValuesKalici
24// (KALICI oldugu icin --enable-preview GEREKMEZ.)
25// ============================================================================
26
27import java.util.concurrent.Callable;
28
29public class ScopedValuesKalici {
30
31 // ------------------------------------------------------------------------
32 // ScopedValue tanimi: tum uygulama boyunca paylasilan, ama degeri sadece
33 // belirli bir "scope" (kapsam) icinde gecerli olan baglam.
34 // Tipik kullanim: oturum acmis kullanicinin kimligi, istek (request) ID'si,
35 // dil/lokal bilgisi, yetki seviyesi gibi "baglamsal" veriler.
36 // ------------------------------------------------------------------------
37 private static final ScopedValue<Kullanici> AKTIF_KULLANICI = ScopedValue.newInstance();
38 private static final ScopedValue<String> ISTEK_ID = ScopedValue.newInstance();
39
40 // Basit bir kullanici modeli (record ile)
41 record Kullanici(String kullaniciAdi, String rol) {}
42
43 public static void main(String[] args) {
44 System.out.println("=== Java 25: Scoped Values (KALICI) ===\n");
45
46 threadLocalVsScopedValueAciklama();
47
48 System.out.println("\n--- GERCEK HAYAT SENARYOSU: Web istegi baglami ---");
49 // Bir web sunucusunun gelen istegi isledigini hayal edin.
50 // Her istek icin kullaniciyi ve istek ID'sini baglama koyuyoruz.
51 gelenIstegiIsle(new Kullanici("ayse", "ADMIN"), "REQ-1001");
52 System.out.println();
53 gelenIstegiIsle(new Kullanici("mehmet", "USER"), "REQ-1002");
54
55 System.out.println("\n--- KAPSAM DISI ERISIM (hata yonetimi) ---");
56 try {
57 // Scope disinda deger okumak istisna firlatir.
58 System.out.println(AKTIF_KULLANICI.get());
59 } catch (Exception e) {
60 System.out.println("Beklenen hata: scope disinda deger okunamaz -> "
61 + e.getClass().getSimpleName());
62 }
63 }
64
65 // ------------------------------------------------------------------------
66 // THREADLOCAL vs SCOPEDVALUE
67 // ------------------------------------------------------------------------
68 static void threadLocalVsScopedValueAciklama() {
69 System.out.println(">> ESKI YONTEM: ThreadLocal");
70 System.out.println(" ThreadLocal<Kullanici> tl = new ThreadLocal<>();");
71 System.out.println(" tl.set(kullanici); // DEGISTIRILEBILIR (mutable)");
72 System.out.println(" ... is bitince ...");
73 System.out.println(" tl.remove(); // UNUTULURSA bellek sizintisi!");
74 System.out.println(" Sorunlar:");
75 System.out.println(" - remove() unutulursa thread havuzlarinda sizinti olur.");
76 System.out.println(" - Her yerden set() ile degistirilebilir -> izlenmesi zor.");
77 System.out.println(" - Milyonlarca sanal thread'de hafiza maliyeti yuksek.\n");
78
79 System.out.println(">> YENI YONTEM: ScopedValue");
80 System.out.println(" ScopedValue.where(AKTIF_KULLANICI, kullanici)");
81 System.out.println(" .run(() -> { ... }); // sadece bu blokta gecerli");
82 System.out.println(" Avantajlar:");
83 System.out.println(" - DEGISMEZ: blok icinde deger degistirilemez -> guvenli.");
84 System.out.println(" - OTOMATIK temizlik: blok bitince deger gecersizlesir,");
85 System.out.println(" remove() cagirmaya gerek YOK.");
86 System.out.println(" - Sanal thread dostu: alt gorevlere otomatik miras kalir.");
87 System.out.println(" - Kapsam acikca bellidir (lexical scope).\n");
88 }
89
90 // ------------------------------------------------------------------------
91 // GERCEK HAYAT: Gelen bir istegi isleme
92 // ------------------------------------------------------------------------
93 static void gelenIstegiIsle(Kullanici kullanici, String istekId) {
94 // ScopedValue.where(...).run(...) ile baglami SADECE bu blok ve
95 // bu bloktan cagrilan tum alt metotlar icin gecerli kiliyoruz.
96 ScopedValue.where(AKTIF_KULLANICI, kullanici)
97 .where(ISTEK_ID, istekId)
98 .run(() -> {
99 System.out.println("[" + istekId + "] Istek alindi.");
100 // Alt katmanlar baglami parametre tasimadan okuyabilir:
101 servisKatmaniCagir();
102 });
103 }
104
105 // Bu metot kullanici parametresi ALMADI ama baglamdan okuyabiliyor.
106 static void servisKatmaniCagir() {
107 String istekId = ISTEK_ID.get();
108 System.out.println("[" + istekId + "] Servis katmani calisiyor...");
109 veriErisimKatmaniCagir();
110 }
111
112 static void veriErisimKatmaniCagir() {
113 // En alt katman bile, parametre zinciri olmadan aktif kullaniciya erisir.
114 Kullanici k = AKTIF_KULLANICI.get();
115 String istekId = ISTEK_ID.get();
116 System.out.println("[" + istekId + "] Veri erisimi: kullanici="
117 + k.kullaniciAdi() + ", rol=" + k.rol());
118
119 // Yetki kontrolu ornegi:
120 if ("ADMIN".equals(k.rol())) {
121 System.out.println("[" + istekId + "] -> ADMIN: tum kayitlara erisim verildi.");
122 } else {
123 System.out.println("[" + istekId + "] -> USER: sadece kendi kayitlarina erisim.");
124 }
125 }
126
127 // ------------------------------------------------------------------------
128 // Deger DONDUREN bir scope ornegi (call ile) - referans amacli
129 // ------------------------------------------------------------------------
130 @SuppressWarnings("unused")
131 static <T> T baglamdaCalistir(Kullanici k, Callable<T> gorev) throws Exception {
132 // run(Runnable) deger dondurmez; deger dondurmek icin call(Callable) kullanilir.
133 return ScopedValue.where(AKTIF_KULLANICI, k).call(gorev);
134 }
135}Bu sürüm-analizi örneği tek dosya olarak yerel JDK 21 ile çalıştırılamadı (bağımsız bir main içermeyebilir ya da daha yeni bir JDK / önizleme özelliği gerektirir). İlgili dil özelliği yukarıdaki anlatım ve kodda gösterilmiştir.
StableValuesPreview
ortam gerekir1// ============================================================================
2// Java 25 - Stable Values (JEP 502 - PREVIEW)
3// ============================================================================
4// DIKKAT: Stable Values, Java 25'te HALA PREVIEW asamasindadir (JEP 502).
5// Yani API ileride degisebilir ve calistirmak icin --enable-preview gerekir.
6//
7// DERLEME / CALISTIRMA (Java 25 - PREVIEW):
8// javac --release 25 --enable-preview StableValuesPreview.java
9// java --enable-preview StableValuesPreview
10//
11// NEDIR:
12// StableValue<T>, bir defaya mahsus (en fazla bir kez) atanan, ondan
13// sonra DEGISMEZ (immutable) hale gelen bir "tutucu"dur. Asil amaci:
14// LAZY (tembel/gec) baslatma -> deger ilk ihtiyac aninda hesaplanir,
15// sonra cache'lenir. JIT derleyici, deger atandiktan sonra onu adeta
16// 'final' gibi optimize edebilir (constant folding). Yani:
17// "final'in performansi + lazy'nin esnekligi"
18//
19// NEDEN GELDI:
20// - 'final' alanlar yapilandiricida HEMEN atanmak zorundadir (lazy degil).
21// - Lazy yapmak icin tarihsel olarak "double-checked locking" gibi hata
22// yapmaya cok acik desenler kullanilirdi.
23// - StableValue, bu deseni guvenli, kisa ve performansli sekilde sunar.
24// ============================================================================
25
26import java.util.function.Supplier;
27
28public class StableValuesPreview {
29
30 public static void main(String[] args) {
31 System.out.println("=== Java 25: Stable Values (PREVIEW - JEP 502) ===\n");
32 System.out.println("(Calistirma: java --enable-preview StableValuesPreview)\n");
33
34 eskiDoubleCheckedLockingAciklama();
35
36 System.out.println("\n--- StableValue ile lazy init ornegi ---");
37 Konfigurasyon konfig = new Konfigurasyon();
38
39 System.out.println("Nesne olusturuldu; agir kaynak HENUZ hesaplanmadi.");
40 System.out.println("(Tembellik: ilk get() cagrilana kadar hesaplama yok.)\n");
41
42 // Ilk erisim -> hesaplama burada bir kez yapilir:
43 System.out.println("1. erisim: " + konfig.getBaglantiDizesi());
44 // Ikinci erisim -> cache'ten gelir, tekrar hesaplanmaz:
45 System.out.println("2. erisim: " + konfig.getBaglantiDizesi());
46 System.out.println("3. erisim: " + konfig.getBaglantiDizesi());
47
48 System.out.println("\nDikkat: 'AGIR HESAPLAMA' yazisi sadece BIR KEZ gorunmeli.");
49 }
50
51 static void eskiDoubleCheckedLockingAciklama() {
52 System.out.println(">> ESKI YONTEM: Double-Checked Locking (hata yapmaya acik)");
53 System.out.println(" private volatile Agir nesne;");
54 System.out.println(" public Agir get() {");
55 System.out.println(" Agir sonuc = nesne;");
56 System.out.println(" if (sonuc == null) {");
57 System.out.println(" synchronized (this) {");
58 System.out.println(" sonuc = nesne;");
59 System.out.println(" if (sonuc == null)");
60 System.out.println(" nesne = sonuc = new Agir();");
61 System.out.println(" }");
62 System.out.println(" }");
63 System.out.println(" return sonuc;");
64 System.out.println(" }");
65 System.out.println(" Sorunlar: volatile unutulursa BUG; cok satirli, okunmasi zor;");
66 System.out.println(" JIT 'final' kadar iyi optimize edemez.\n");
67
68 System.out.println(">> YENI YONTEM: StableValue (PREVIEW)");
69 System.out.println(" private final StableValue<Agir> nesne = StableValue.of();");
70 System.out.println(" public Agir get() {");
71 System.out.println(" return nesne.orElseSet(() -> new Agir());");
72 System.out.println(" }");
73 System.out.println(" Avantajlar: tek satir, thread-safe, JIT 'final' gibi optimize");
74 System.out.println(" edebilir (constant folding). volatile/synchronized derdi yok.\n");
75 System.out.println(" NOT: API isimleri PREVIEW oldugu icin (StableValue.of /");
76 System.out.println(" orElseSet vb.) surumler arasi degisebilir; resmi JEP'e bakin.");
77 }
78
79 // ------------------------------------------------------------------------
80 // GERCEK HAYAT: Konfigurasyon icindeki pahali bir baglanti dizesini
81 // yalnizca ilk ihtiyac aninda, bir kez hesaplayip cache'lemek.
82 // ------------------------------------------------------------------------
83 static class Konfigurasyon {
84
85 // StableValue tutucusu: bir kez set edilir, sonra degismez.
86 // PREVIEW API'si: StableValue.of() bos bir tutucu olusturur.
87 private final StableValue<String> baglantiDizesi = StableValue.of();
88
89 String getBaglantiDizesi() {
90 // orElseSet: deger yoksa Supplier ile uretir+cache'ler, varsa cache'i dondurur.
91 // Supplier en fazla BIR KEZ calisir (thread-safe garantili).
92 return baglantiDizesi.orElseSet(this::agirHesaplama);
93 }
94
95 // Pahali hesaplamayi temsil eden metot.
96 private String agirHesaplama() {
97 System.out.println(" [AGIR HESAPLAMA calisiyor... bir kez]");
98 try {
99 Thread.sleep(300); // pahali I/O'yu simule et
100 } catch (InterruptedException e) {
101 Thread.currentThread().interrupt();
102 }
103 return "jdbc://veritabani:5432/uygulama?havuz=20";
104 }
105 }
106
107 // ------------------------------------------------------------------------
108 // Referans: StableValue'yu bir Supplier gibi de kullanabilirsiniz.
109 // Asagidaki yardimci, klasik Supplier imzasiyla nasil sarilabilecegini
110 // gosterir (gercek API farkli yardimci metotlar sunabilir).
111 // ------------------------------------------------------------------------
112 @SuppressWarnings("unused")
113 static <T> Supplier<T> tembelSupplier(Supplier<T> kaynak) {
114 StableValue<T> sv = StableValue.of();
115 return () -> sv.orElseSet(kaynak);
116 }
117}Bu sürüm-analizi örneği tek dosya olarak yerel JDK 21 ile çalıştırılamadı (bağımsız bir main içermeyebilir ya da daha yeni bir JDK / önizleme özelliği gerektirir). İlgili dil özelliği yukarıdaki anlatım ve kodda gösterilmiştir.
StructuredConcurrencyGuncel
ortam gerekir1// ============================================================================
2// Java 25 - Structured Concurrency (JEP 505 - HALA PREVIEW)
3// ============================================================================
4// DURUSTLUK NOTU: Structured Concurrency, Java 25'te HALA PREVIEW
5// asamasindadir (JEP 505 - 5. preview). KALICI DEGILDIR. Bu nedenle:
6// - --enable-preview ile derlemek/calistirmak gerekir,
7// - API ileride degisebilir.
8//
9// ONEMLI: API, son preview'larda DEGISTI. Eski "StructuredTaskScope.fork()
10// + ShutdownOnFailure" yaklasimi yerine, Java 25'te (JEP 505) StructuredTaskScope
11// bir "Joiner" (birlestirici) ile, genelde StructuredTaskScope.open(...) sekilde
12// acilir. Asagidaki ornek, kavrami gostermek icin GUNCEL preview API tarzini
13// kullanir. Surumunuzdeki KESIN imzalar icin resmi JEP 505'e bakin.
14//
15// DERLEME / CALISTIRMA (Java 25 - PREVIEW):
16// javac --release 25 --enable-preview StructuredConcurrencyGuncel.java
17// java --enable-preview StructuredConcurrencyGuncel
18//
19// NEDIR:
20// Structured Concurrency, ayni mantiksal isi yapan birden cok es zamanli
21// alt gorevi TEK BIR birim gibi ele alir. Anladigimiz "yapisal programlama"
22// mantigini (bir blok girilir, blok bitince her sey toparlanir) es zamanli
23// gorevlere tasir:
24// - Alt gorevler bir scope icinde acilir (fork edilir).
25// - Biri basarisiz olursa digerleri OTOMATIK iptal edilir.
26// - Scope bitmeden ana akis devam ETMEZ (sizan thread olmaz).
27// ============================================================================
28
29import java.util.concurrent.StructuredTaskScope;
30import java.time.Duration;
31
32public class StructuredConcurrencyGuncel {
33
34 public static void main(String[] args) throws Exception {
35 System.out.println("=== Java 25: Structured Concurrency (PREVIEW - JEP 505) ===\n");
36 System.out.println("(Calistirma: java --enable-preview StructuredConcurrencyGuncel)\n");
37
38 eskiYontemAciklama();
39
40 System.out.println("\n--- 1) BASARILI senaryo: birden cok servisten paralel veri ---");
41 try {
42 KullaniciProfili profil = profilGetir(42);
43 System.out.println("Birlesik profil -> " + profil);
44 } catch (Exception e) {
45 System.out.println("Hata: " + e.getMessage());
46 }
47
48 System.out.println("\n--- 2) HATA YAYILIMI / IPTAL senaryosu ---");
49 try {
50 profilGetirHataliServisIle(99);
51 } catch (Exception e) {
52 System.out.println("Beklenen davranis: bir gorev patlayinca digerleri iptal");
53 System.out.println("edildi ve hata yukari yayildi -> "
54 + e.getClass().getSimpleName() + ": " + e.getMessage());
55 }
56 }
57
58 static void eskiYontemAciklama() {
59 System.out.println(">> ESKI YONTEM: ExecutorService + Future (yapisiz)");
60 System.out.println(" var ex = Executors.newFixedThreadPool(2);");
61 System.out.println(" Future<A> f1 = ex.submit(...);");
62 System.out.println(" Future<B> f2 = ex.submit(...);");
63 System.out.println(" A a = f1.get(); // f1 patlarsa f2 IPTAL EDILMEZ -> sizinti");
64 System.out.println(" B b = f2.get(); // iptal/zaman asimi yonetimi elle yapilir");
65 System.out.println(" Sorunlar: iptal yayilimi elle; thread sizintisi riski; hata");
66 System.out.println(" yonetimi dagilmis; iliski (parent/child) kaybolur.\n");
67
68 System.out.println(">> YENI YONTEM: StructuredTaskScope (PREVIEW)");
69 System.out.println(" try (var scope = StructuredTaskScope.open(...)) {");
70 System.out.println(" var t1 = scope.fork(() -> servisA());");
71 System.out.println(" var t2 = scope.fork(() -> servisB());");
72 System.out.println(" scope.join(); // ikisini birlikte bekle");
73 System.out.println(" return birlestir(t1.get(), t2.get());");
74 System.out.println(" } // blok bitince TUM alt gorevler toparlanir");
75 System.out.println(" Avantaj: biri patlarsa digeri otomatik iptal; sizinti yok;");
76 System.out.println(" hata ve iptal yapisal, okunabilir.\n");
77 }
78
79 // Basit modeller
80 record Temel(int id, String ad) {}
81 record SiparisOzeti(int adet, double toplam) {}
82 record KullaniciProfili(int id, String ad, int siparisAdet, double siparisToplam) {}
83
84 // ------------------------------------------------------------------------
85 // 1) BASARILI: iki servisten paralel veri cekip birlestirme.
86 // NOT: Asagidaki StructuredTaskScope.open() ve Joiner kullanimi
87 // Java 25 (JEP 505) preview API tarzini yansitir.
88 // ------------------------------------------------------------------------
89 static KullaniciProfili profilGetir(int kullaniciId) throws Exception {
90 // open(): tum alt gorevler basarili olursa devam, biri patlarsa hepsini iptal eder.
91 try (var scope = StructuredTaskScope.open(
92 StructuredTaskScope.Joiner.<Object>allSuccessfulOrThrow())) {
93
94 // Iki alt gorevi paralel baslat (sanal thread'lerde):
95 StructuredTaskScope.Subtask<Temel> temelGorev =
96 scope.fork(() -> temelBilgiServisi(kullaniciId));
97 StructuredTaskScope.Subtask<SiparisOzeti> siparisGorev =
98 scope.fork(() -> siparisServisi(kullaniciId));
99
100 // Hepsinin bitmesini bekle; biri patlarsa burada istisna firlar.
101 scope.join();
102
103 // Buraya gelindiyse ikisi de basarili:
104 Temel temel = temelGorev.get();
105 SiparisOzeti siparis = siparisGorev.get();
106 return new KullaniciProfili(
107 temel.id(), temel.ad(), siparis.adet(), siparis.toplam());
108 }
109 }
110
111 // ------------------------------------------------------------------------
112 // 2) HATA YAYILIMI: siparis servisi patlar -> temel servis iptal edilir,
113 // hata yukari yayilir.
114 // ------------------------------------------------------------------------
115 static KullaniciProfili profilGetirHataliServisIle(int kullaniciId) throws Exception {
116 try (var scope = StructuredTaskScope.open(
117 StructuredTaskScope.Joiner.<Object>allSuccessfulOrThrow())) {
118
119 scope.fork(() -> temelBilgiServisi(kullaniciId));
120 scope.fork(() -> hataliSiparisServisi(kullaniciId)); // patlar
121
122 scope.join(); // burada istisna firlar
123 throw new IllegalStateException("buraya ulasilmamali");
124 }
125 }
126
127 // --- Sahte servisler (paralel I/O simulasyonu) ---
128
129 static Temel temelBilgiServisi(int id) throws InterruptedException {
130 System.out.println(" [temel] cagrildi...");
131 Thread.sleep(Duration.ofMillis(200)); // ag gecikmesi simulasyonu
132 System.out.println(" [temel] tamam.");
133 return new Temel(id, "Kullanici-" + id);
134 }
135
136 static SiparisOzeti siparisServisi(int id) throws InterruptedException {
137 System.out.println(" [siparis] cagrildi...");
138 Thread.sleep(Duration.ofMillis(300));
139 System.out.println(" [siparis] tamam.");
140 return new SiparisOzeti(3, 1499.90);
141 }
142
143 static SiparisOzeti hataliSiparisServisi(int id) throws InterruptedException {
144 System.out.println(" [siparis-HATALI] cagrildi...");
145 Thread.sleep(Duration.ofMillis(100));
146 throw new RuntimeException("Siparis servisi cevap veremedi (HTTP 503)");
147 }
148}Bu sürüm-analizi örneği tek dosya olarak yerel JDK 21 ile çalıştırılamadı (bağımsız bir main içermeyebilir ya da daha yeni bir JDK / önizleme özelliği gerektirir). İlgili dil özelliği yukarıdaki anlatım ve kodda gösterilmiştir.