Java 11 (Eylül 2018) — LTS Sürüm Detaylı Analizi
> Çıkış Tarihi: Eylül 2018 > Sürüm Tipi: LTS (Long Term Support — Uzun Süreli Destek) ⭐ > Önceki LTS: Java 8 (Mart 2014) > Sonraki LTS: Java 17 (Eylül 2021)
Java 11 (Eylül 2018) — LTS Sürüm Detaylı Analizi
Çıkış Tarihi: Eylül 2018 Sürüm Tipi: LTS (Long Term Support — Uzun Süreli Destek) ⭐ Önceki LTS: Java 8 (Mart 2014) Sonraki LTS: Java 17 (Eylül 2021)
🏆 Neden LTS ÇOK Önemli? (Kurumsal Bakış)
Java 11, Java 8'den sonraki ilk LTS sürümüdür ve bu yüzden kurumsal dünyada devasa bir öneme sahiptir. Java 9 ve 10 "feature release" (özellik sürümü) idi ve sadece 6 ay destek aldı. Java 11 ise yıllarca destek alır.
LTS Nedir, Neden Hayati?
Oracle, Java 9'dan itibaren 6 aylık sürüm takvimine geçti. Yani her 6 ayda bir yeni Java sürümü çıkıyor (9, 10, 11, 12, ...). Ancak bu sürümlerin çoğu sadece 6 ay güncelleme/güvenlik yaması alır. LTS sürümler ise istisnadır:
| Konu | Normal (Feature) Sürüm | LTS Sürüm (Java 11) |
|---|---|---|
| Destek penceresi | ~6 ay | Yıllarca (genelde 8+ yıl genişletilmiş destek) |
| Güvenlik yaması | Bir sonraki sürüm çıkınca biter | Uzun süre devam eder |
| Kurumsal uygunluk | Düşük (sürekli yükseltme baskısı) | Yüksek (stabil zemin) |
| Üretim ortamı önerisi | Genelde önerilmez | Kesinlikle önerilir |
Neden Şirketler Java 8'den Sonra En Çok 11'e Geçti?
-
Üretim Ortamı Stabilitesi: Bir bankanın, sigortanın veya e-ticaret devinin sistemini her 6 ayda bir Java sürümü yükseltmesi mümkün değildir. Test, sertifikasyon, regresyon süreçleri aylar sürer. LTS, "bir kez geç, yıllarca rahat et" demektir.
-
Uzun Destek Penceresi: Java 11, çıkışından yıllar sonra bile güvenlik güncellemesi alır. Bu, denetim/uyumluluk (audit/compliance) gereksinimi olan kurumlar için zorunludur.
-
Güvenlik Güncellemeleri: LTS olmayan sürümlerde, 6 ay sonra güvenlik açığı bulunsa bile yama gelmez; bir üst sürüme geçmek zorunda kalırsın. LTS'te bu risk yoktur.
-
Ekosistem Desteği: Spring, Hibernate, Tomcat, build araçları (Maven, Gradle) ve bulut sağlayıcıları (AWS, Azure) öncelikle LTS sürümleri hedef alır ve uzun süre destekler.
-
Lisans/Dağıtım Netliği: Java 11 döneminde OpenJDK dağıtımları (Adoptium/ Eclipse Temurin, Amazon Corretto, Azul Zulu, Red Hat) yaygınlaştı; ücretsiz ve uzun destekli LTS yapıları kurumlar için cazip oldu.
Özet: Java 8 → Java 11 geçişi, "bir sonraki güvenli liman"a geçiş olarak görüldü. Çoğu kurum 9 ve 10'u tamamen atlayıp doğrudan 11'e taşındı.
📋 Genel Bakış — Java 11 Yenilikleri
| # | Özellik | JEP | Örnek Dosya |
|---|---|---|---|
| 1 | Standart HTTP Client (java.net.http) | JEP 321 | YeniHttpClient.java |
| 2 | Yeni String metotları (strip, isBlank, lines, repeat) | JEP 327/(çeşitli) | StringYeniMetotlar.java |
| 3 | Files.readString / Files.writeString | (API) | FilesReadWriteString.java |
| 4 | Lambda parametrelerinde var | JEP 323 | VarLambdaParametre.java |
| 5 | Tek dosya kaynak kodu çalıştırma | JEP 330 | TekDosyaCalistirma.java |
| 6 | Collection.toArray(IntFunction) | (API) | StringYeniMetotlar.java içinde |
| 7 | Epsilon GC (deneysel) | JEP 318 | (README) |
| 8 | ZGC (deneysel) | JEP 333 | (README) |
| 9 | Flight Recorder | JEP 328 | (README) |
1) Standart HTTP Client — java.net.http (JEP 321)
📄 Örnek: YeniHttpClient.java
NEDIR?
Java 11 ile java.net.http paketi standart (kararlı) hale geldi. Java 9'da
jdk.incubator.http adıyla incubator (kuluçka/deneysel) modül olarak gelmişti.
Java 11'de incubator'dan çıkıp tam JDK API'si oldu. HttpClient, HttpRequest,
HttpResponse üçlüsü ile modern HTTP istekleri atılır.
NEDEN GELDI? (Hangi problem)
Eski HttpURLConnection (1997, Java 1.1) çok düşük seviyeli, HTTP/2 desteği
yok, asenkron desteği yok, WebSocket yok ve aşırı boilerplate kod
gerektiriyordu. Bu yüzden herkes 3. parti kütüphanelere (OkHttp, Apache
HttpClient) mecbur kalıyordu.
NE ISE YARAR?
HTTP/1.1 + HTTP/2, senkron (send) ve asenkron (sendAsync), WebSocket,
Reactive Streams tabanlı gövde işleme, builder pattern ile temiz kod.
NEREDE KOLAYLIK SAGLAR?
Mikroservisler arası REST çağrıları, 3. parti API entegrasyonları, paralel/async yüksek performanslı istekler — hepsi harici kütüphane olmadan.
ESKI vs YENI
// ESKI (HttpURLConnection) — ~20+ satır: URL url = new URL("https://api.com/data"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String line; StringBuilder sb = new StringBuilder(); while ((line = in.readLine()) != null) sb.append(line); in.close(); con.disconnect(); String body = sb.toString(); // YENI (Java 11) — 3 satır: HttpClient client = HttpClient.newHttpClient(); HttpResponse<String> r = client.send(request, BodyHandlers.ofString()); String body = r.body();
GERCEK HAYAT ORNEGI
E-ticaret ürün sayfası için stok, fiyat ve yorum servislerine paralel async istek atıp toplam süreyi 300ms'den ~100ms'ye düşürmek.
2) Yeni String Metotları
📄 Örnek: StringYeniMetotlar.java
NEDIR?
strip(), stripLeading(), stripTrailing(), isBlank(), lines(),
repeat(int).
NEDEN GELDI?
- strip vs trim: Eski
trim()yalnızca<= U+0020karakterleri siler, Unicode boşlukları (örn. U+00A0, U+2003) tanımaz.strip()iseCharacter.isWhitespace()kullanır ve tüm Unicode boşlukları temizler. - isBlank:
isEmpty()sadece""için true; içi boşluk dolu" "için false döner.isBlank()"boş veya sadece boşluk" sorusunu doğru cevaplar. - lines:
split("\n")Windows\r\nile sorun çıkarır;lines()tüm satır sonlarını doğru tanır ve lazyStream<String>verir. - repeat: Bir metni N kez tekrarlamak için döngü/StringBuilder yazma derdini bitirir.
ESKI vs YENI
// ESKI: // YENI (Java 11): s.replaceAll("^\\s+|\\s+$", ""); s.strip(); s == null || s.trim().isEmpty(); s.isBlank(); s.split("\\r?\\n"); s.lines(); /* StringBuilder döngüsü */ "=".repeat(40);
GERCEK HAYAT ORNEGI
Form verisi temizleme, log dosyası satır işleme, konsol raporu/tablo çizme.
6) Collection.toArray(IntFunction) — BONUS
📄 Örnek: StringYeniMetotlar.java içinde (Bölüm 5)
NEDIR?
Bir koleksiyonu tipli diziye çevirirken, boş dizi nesnesi geçmek yerine bir method reference verilebilir:
// ESKI: String[] dizi = list.toArray(new String[0]); // YENI: String[] dizi = list.toArray(String[]::new);
Daha okunabilir ve niyet açısından daha nettir.
3) Files.readString / Files.writeString
📄 Örnek: FilesReadWriteString.java
NEDIR?
Files.readString(Path) dosyanın tüm içeriğini tek bir String'e okur;
Files.writeString(Path, CharSequence) bir String'i dosyaya yazar. Varsayılan
charset UTF-8'dir; Charset alan overload'lar da vardır.
NEDEN GELDI?
Tüm dosyayı tek String okumak/yazmak çok yaygın ama eskiden tek satırlık yolu
yoktu: Files.readAllBytes + new String, BufferedReader döngüsü ya da
Files.lines().collect(joining) gerekiyordu — hepsi uzun ve charset hatasına
açıktı.
ESKI vs YENI
// ESKI: byte[] b = Files.readAllBytes(path); String s = new String(b, StandardCharsets.UTF_8); // charset unutulursa Türkçe bozulur // YENI: String s = Files.readString(path); // tek satır, UTF-8 varsayılan Files.writeString(path, s);
NEREDE KOLAYLIK SAGLAR?
Config dosyaları (.properties/.json/.yaml), şablon dosyaları, SQL script'leri, küçük metin dosyaları okuma/yazma.
RISK
readString tüm dosyayı belleğe alır → çok büyük dosyalarda OOM riski. Büyük
dosyalar için hâlâ Files.lines (stream) tercih edilmeli.
4) Lambda Parametrelerinde var (JEP 323)
📄 Örnek: VarLambdaParametre.java
NEDIR?
Java 10'da gelen var (yerel değişken tip çıkarımı) Java 11'de lambda
parametrelerinde de kullanılabilir: (var a, var b) -> a + b.
NEDEN GELDI?
Tek başına çok kısaltma sağlamaz (zaten (a,b) -> a+b yazılabiliyor). Asıl
fayda: lambda parametresine annotation (örn. @NonNull) eklemek için bir
tipe ihtiyaç var; var bunu sağlarken uzun tip adını yazmaktan kurtarır:
(@NonNull var a, @NonNull var b) -> a + b // var ile mümkün
KURALLAR
- Ya hepsi
varya hiçbiri — karıştırılamaz ((var a, b)❌,(var a, Integer b)❌). - Parantez zorunlu — tek parametrede bile (
var x -> x❌,(var x) -> x✓).
ESKI (Java 10) vs YENI (Java 11)
// Java 10: (a, b) -> a + b // var YAZILAMAZ // Java 11: (var a, var b) -> a + b // var YAZILABILIR
5) Tek Dosya Kaynak Kodu Çalıştırma (JEP 330)
📄 Örnek: TekDosyaCalistirma.java
NEDIR?
Bir .java dosyası önceden derlemeden doğrudan çalıştırılabilir:
java TekDosyaCalistirma.java
Java dosyayı bellekte derler ve çalıştırır; disk'e .class yazmaz.
NEDEN GELDI?
Öğrenenler ve hızlı denemeler için iki adımlı süreç (javac → java)
gereksiz bir engeldi. Python/Ruby gibi "yaz-çalıştır" deneyimi getirildi.
ESKI vs YENI
# ESKI (iki adım): javac Merhaba.java # .class oluşur java Merhaba # YENI (tek adım): java Merhaba.java # bellekte derle + çalıştır
SHEBANG (#!) ile Script
Uzantısız bir dosyada ilk satıra #!/usr/bin/java --source 11 konup
chmod +x ile çalıştırma izni verilirse, dosya bash/python script'i gibi
./dosya şeklinde çalıştırılabilir. (Shebang dosyası .java uzantılı olamaz.)
NEREDE KOLAYLIK SAGLAR?
Öğrenme, hızlı prototipleme, küçük script'ler, API deneme.
7) Epsilon GC — "No-Op" Garbage Collector (JEP 318, deneysel)
NEDIR?
Epsilon, çöp toplamayan (no-op) deneysel bir GC'dir. Bellek ayırır ama hiç geri toplamaz; bellek dolunca uygulama durur.
NEDEN / NEREDE?
- Performans testi: GC gürültüsü olmadan saf uygulama performansını ölçmek.
- Çok kısa ömürlü işler: Belleğin asla dolmayacağı kısa programlar (GC maliyetini sıfırlamak).
- Bellek baskısı testi: Bir uygulamanın gerçekten ne kadar bellek tükettiğini görmek.
Açma: -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
8) ZGC — Z Garbage Collector (JEP 333, deneysel)
NEDIR?
Çok düşük gecikmeli (low-latency), ölçeklenebilir bir çöp toplayıcı. Hedefi: duraklama (pause) sürelerini 10ms altında tutmak — heap boyutundan (MB'den TB'ye) bağımsız olarak.
NEDEN / NEREDE?
Büyük heap'li, düşük gecikme isteyen uygulamalar (finansal işlem sistemleri, büyük önbellekler, gerçek zamanlı analiz). Java 11'de Linux/x64'te deneysel olarak geldi (sonraki sürümlerde production-ready oldu).
Açma: -XX:+UnlockExperimentalVMOptions -XX:+UseZGC
9) Java Flight Recorder — JFR (JEP 328)
NEDIR?
JFR, JVM içinde çalışan düşük maliyetli bir profilleme/teşhis (profiling/ diagnostics) aracıdır. Önceden ticari (Oracle) bir özellikti; Java 11 ile OpenJDK'ye açık kaynak olarak eklendi.
NEDEN / NEREDE?
Üretim ortamında, neredeyse sıfır ek yük (overhead ~%1) ile uygulamanın iç verilerini (GC, thread, I/O, bellek, kilitler) kaydeder. Sonradan JDK Mission Control (JMC) ile analiz edilir. Performans sorunu/bellek sızıntısı teşhisi için kurumsal ortamlarda paha biçilemez.
Örnek: java -XX:+FlightRecorder -XX:StartFlightRecording=duration=60s,filename=kayit.jfr Uygulama
🔄 Java 10'dan (ve Java 8'den) Java 11'e GEÇİŞTE NE DEĞİŞTİ?
Java 8 → Java 11 (Büyük Sıçrama — en yaygın kurumsal geçiş)
- Modül sistemi (JPMS) Java 9'da gelmişti; 11'de olgunlaştı.
module-info.javave modüler classpath kavramları geldi. - Java EE / CORBA modülleri KALDIRILDI (en kritik kırılma — aşağıda).
- Yeni HTTP Client,
var, yeni String/Files metotları, tek dosya çalıştırma. javafxartık JDK ile gelmiyor (ayrı bağımlılık — OpenJFX).- Birçok deprecated API kaldırıldı; bazı internal API'ler (sun.misc.*) erişimi kısıtlandı.
Java 10 → Java 11 (Küçük ama önemli)
varartık lambda parametrelerinde de kullanılabiliyor (JEP 323).- Yeni String/Files metotları, standart HTTP Client, JFR, ZGC, Epsilon GC.
- Java EE/CORBA modülleri 10'da hâlâ
--add-modulesile kullanılabilirken 11'de tamamen kaldırıldı.
⚖️ Avantaj / Dezavantaj / RISK
✅ Avantajlar
- LTS → uzun destek, üretim için ideal, kurumsal stabilite.
- Modern, harici kütüphanesiz HTTP Client.
- Daha temiz String/Files API'leri → daha az boilerplate.
- Yeni GC seçenekleri (ZGC, Epsilon) ve güçlü teşhis (JFR).
- Tek dosya çalıştırma ile hızlı deneme/öğrenme.
- Performans iyileştirmeleri ve daha küçük çalışma zamanı (jlink ile özel runtime).
⚠️ Dezavantajlar
- Java 8'den geçiş, kaldırılan modüller nedeniyle kod değişikliği gerektirebilir.
- Modül sistemi öğrenme eğrisi getirir.
- Bazı eski/3. parti kütüphaneler Java 11'de uyumsuz olabilir (özellikle internal API kullananlar).
🚨 RISK — Java EE ve CORBA Modüllerinin KALDIRILMASI (JEP 320)
Bu, Java 8 → Java 11 geçişinde en sık karşılaşılan ve en sancılı sorundur.
Java 11 ile aşağıdaki Java EE ve CORBA modülleri JDK'den tamamen kaldırıldı:
| Kaldırılan Paket / Modül | İşlevi |
|---|---|
java.xml.bind (JAXB — javax.xml.bind.*) | XML ↔ Java nesne bağlama (marshalling) |
java.xml.ws (JAX-WS — javax.xml.ws.*, javax.jws.*) | SOAP web servisleri |
java.activation (JAF — javax.activation.*) | Veri tipi yönetimi (JAXB/JAX-WS bağımlılığı) |
java.corba (org.omg.CORBA.*) | CORBA dağıtık nesne mimarisi |
java.transaction (javax.transaction.* — kısmi) | İşlem (transaction) API'si |
java.xml.ws.annotation (javax.annotation.* — örn. @PostConstruct) | Ortak anotasyonlar |
Bu Neden Kurumsal Geçişte Sorun Yaratır?
Java 8 döneminde yazılmış birçok kurumsal uygulama, farkında bile olmadan bu
modülleri kullanıyordu (JDK ile geldikleri için classpath'te otomatik vardılar).
Örneğin JAXB ile XML işleyen, SOAP servisine bağlanan, @PostConstruct kullanan
kodlar... Java 11'e geçince bu sınıflar artık JDK'de olmadığı için çalışma
zamanında patlar:
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException java.lang.ClassNotFoundException: javax.xml.bind.JAXBContext NoClassDefFoundError: javax/annotation/PostConstruct
Kod Java 8'de sorunsuz derlenir ve çalışır; Java 11'de aynı kod NoClassDefFoundError verir. Bu yüzden geçiş öncesi mutlaka bağımlılık taraması yapılmalıdır.
ÇÖZÜM — Eksik Modülleri Bağımlılık Olarak Ekleyin
Kaldırılan modüller artık bağımsız kütüphaneler olarak (Maven Central'dan) eklenir. Örnek Maven bağımlılıkları:
<!-- JAXB API + Runtime --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.3</version> </dependency> <!-- JAX-WS (SOAP) --> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-rt</artifactId> <version>2.3.3</version> </dependency> <!-- JavaBeans Activation Framework --> <dependency> <groupId>com.sun.activation</groupId> <artifactId>javax.activation</artifactId> <version>1.2.0</version> </dependency> <!-- Common Annotations (@PostConstruct vb.) --> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>
CORBA için: CORBA'nın resmî bir standalone yedeği yoktur (
org.omg.*). CORBA kullanan eski sistemler ya GlassFish CORBA gibi 3. parti implementasyonlara taşınmalı ya da daha modern bir iletişim (REST/gRPC) ile yeniden yazılmalıdır. Bu, geçişin en maliyetli kısmı olabilir.
Geçiş Kontrol Listesi
jdepsaracıyla bağımlılıkları tara:jdeps --jdk-internals uygulama.jarjavax.xml.bind,javax.xml.ws,javax.activation,javax.annotation,org.omg.*kullanımlarını ara.- Eksik modülleri yukarıdaki gibi açık bağımlılık olarak ekle.
- Tüm test paketini Java 11 altında çalıştır (sadece derleme yetmez — runtime'da patlar!).
-
- parti kütüphanelerin Java 11 uyumlu sürümlerine yükselt.
▶ Kod Örnekleri(4)
FilesReadWriteString
çalıştırılabilir1import java.io.IOException;
2import java.nio.charset.StandardCharsets;
3import java.nio.file.Files;
4import java.nio.file.Path;
5
6/**
7 * ============================================================================
8 * JAVA 11 - Files.readString / Files.writeString - JEP 330 ile birlikte gelen
9 * pratik dosya I/O metotlari
10 * ============================================================================
11 *
12 * NEDIR?
13 * ------
14 * Java 11, java.nio.file.Files sinifina iki cok kullanisli metot ekledi:
15 * - Files.readString(Path) -> dosyanin TUM icerigini tek String'e okur
16 * - Files.writeString(Path, CharSequence) -> bir String'i dosyaya yazar
17 * Her ikisinin de Charset alan asiri yuklemeleri (overload) vardir.
18 * Varsayilan charset UTF-8'dir.
19 *
20 * NEDEN GELDI? (Hangi problem?)
21 * -----------------------------
22 * Bir dosyanin tum icerigini tek bir String olarak okumak/yazmak gunluk
23 * hayatta cok sik yapilan bir is. Ama Java'da bunu yapmanin "tek satirlik"
24 * basit bir yolu yoktu. Insanlar ya:
25 * - BufferedReader ile satir satir okur (cok kod),
26 * - Files.readAllBytes(path) + new String(bytes, UTF_8) yazar (charset
27 * hatasi yapmaya acik),
28 * - Files.lines(...).collect(joining("\n")) yazar (satir sonu kaybi),
29 * - ya da Apache Commons IO / Guava gibi 3. parti kutuphane kullanirdi.
30 *
31 * NE ISE YARAR / NEREDE KOLAYLIK SAGLAR?
32 * --------------------------------------
33 * - Konfigurasyon dosyalari (.properties, .json, .yaml) okuma
34 * - Template (sablon) dosyalari okuyup icini doldurma
35 * - Kucuk metin dosyalari, SQL script'leri, HTML parcalari okuma
36 * - Log/rapor yazma, ciktiyi dosyaya kaydetme
37 *
38 * GERCEK HAYAT ORNEGI:
39 * --------------------
40 * Bir uygulama, e-posta sablonunu "email_template.html" dosyasindan okuyup
41 * icindeki {isim} gibi yer tutuculari degistirip gonderir. Tek satirda
42 * String oku, replace et, gonder. Eskiden bu 10+ satirdi.
43 *
44 * DIKKAT (RISK): readString tum dosyayi BELLEGE alir. Cok buyuk dosyalarda
45 * (orn. yuzlerce MB) OutOfMemoryError riski vardir. Buyuk dosyalar icin hala
46 * BufferedReader / Files.lines (stream) tercih edilmelidir.
47 * ============================================================================
48 */
49public class FilesReadWriteString {
50
51 public static void main(String[] args) {
52 try {
53 // ================================================================
54 // Gecici bir dosya olusturuyoruz (ornek gercekten calissin diye)
55 // ================================================================
56 Path geciciDosya = Files.createTempFile("java11-ornek", ".txt");
57 System.out.println("Gecici dosya olusturuldu: " + geciciDosya);
58
59 String icerik = "Merhaba Java 11!\n"
60 + "Bu dosya Files.writeString ile yazildi.\n"
61 + "Turkce karakterler: cgiosu CGIOSU\n"
62 + "Ucuncu satir.";
63
64 // ================================================================
65 // 1) YENI YONTEM: Files.writeString ile yazma (UTF-8)
66 // ================================================================
67 // Charset belirtmek istersek StandardCharsets.UTF_8 verebiliriz.
68 Files.writeString(geciciDosya, icerik, StandardCharsets.UTF_8);
69 System.out.println("\n>>> Dosyaya yazildi (Files.writeString).");
70
71 // ================================================================
72 // 2) YENI YONTEM: Files.readString ile okuma (UTF-8)
73 // ================================================================
74 String okunan = Files.readString(geciciDosya, StandardCharsets.UTF_8);
75 System.out.println("\n>>> Dosyadan okunan icerik (Files.readString):");
76 System.out.println("------------------------------------------------");
77 System.out.println(okunan);
78 System.out.println("------------------------------------------------");
79 System.out.println("Okunan karakter sayisi: " + okunan.length());
80
81 // ================================================================
82 // 3) Java 11 lines() ile birlikte kullanim (BONUS)
83 // ================================================================
84 System.out.println("\n>>> Satir satir isleme (String.lines()):");
85 okunan.lines()
86 .filter(satir -> !satir.isBlank())
87 .forEach(satir -> System.out.println(" Satir: " + satir));
88
89 // Temizlik: gecici dosyayi sil
90 Files.deleteIfExists(geciciDosya);
91 System.out.println("\nGecici dosya silindi.");
92
93 } catch (IOException e) {
94 System.out.println("Dosya islemi sirasinda hata: " + e.getMessage());
95 }
96 }
97}
98
99/*
100 * ============================================================================
101 * ESKI vs YENI KARSILASTIRMA
102 * ============================================================================
103 *
104 * --- ESKI YONTEM 1: Files.readAllBytes + new String ---
105 * byte[] bytes = Files.readAllBytes(path);
106 * String icerik = new String(bytes, StandardCharsets.UTF_8);
107 * // Charset unutursan platform varsayilani kullanilir -> Turkce bozulur!
108 *
109 * --- ESKI YONTEM 2: BufferedReader ile satir satir ---
110 * StringBuilder sb = new StringBuilder();
111 * try (BufferedReader br = Files.newBufferedReader(path, UTF_8)) {
112 * String line;
113 * while ((line = br.readLine()) != null) {
114 * sb.append(line).append(System.lineSeparator());
115 * }
116 * }
117 * String icerik = sb.toString(); // ~7 satir + try-with-resources
118 *
119 * --- ESKI YONTEM 3: Files.lines (stream) ---
120 * String icerik;
121 * try (Stream<String> s = Files.lines(path, UTF_8)) {
122 * icerik = s.collect(Collectors.joining("\n"));
123 * // Sondaki satir sonu kaybolur, orijinal birebir korunmaz
124 * }
125 *
126 * --- ESKI YAZMA YONTEMI ---
127 * try (BufferedWriter bw = Files.newBufferedWriter(path, UTF_8)) {
128 * bw.write(icerik);
129 * }
130 *
131 * --- YENI YONTEM (Java 11) ---
132 * String icerik = Files.readString(path); // OKUMA - tek satir
133 * Files.writeString(path, icerik); // YAZMA - tek satir
134 *
135 * OZET TABLO:
136 * | Islem | Eski (satir sayisi) | Yeni Java 11 |
137 * |-------|---------------------|--------------|
138 * | Okuma | 5-7 satir | 1 satir |
139 * | Yazma | 3-4 satir | 1 satir |
140 * | Charset hata riski | Yuksek | Dusuk (UTF-8 varsayilan) |
141 * ============================================================================
142 */StringYeniMetotlar
çalıştırılabilir1import java.util.List;
2import java.util.stream.Collectors;
3
4/**
5 * ============================================================================
6 * JAVA 11 - YENI STRING METOTLARI - JEP 327 (Unicode) + String iyilestirmeleri
7 * ============================================================================
8 *
9 * Java 11 ile String sinifina cok kullanisli metotlar eklendi:
10 * - strip(), stripLeading(), stripTrailing()
11 * - isBlank()
12 * - lines()
13 * - repeat(int)
14 *
15 * Ayrica Collection.toArray(IntFunction) yeniligi de bu dosyada gosterilmistir
16 * (List<String> -> String[] donusumu icin).
17 *
18 * GERCEK HAYAT ORNEGI:
19 * --------------------
20 * Kullanicidan gelen form verilerini (isim, e-posta) temizlemek, log
21 * dosyalarini satir satir islemek, CSV/metin parse etmek, rapor/tablo
22 * cizmek (repeat ile cizgi/bosluk) gibi gunluk islerde cok ise yarar.
23 * ============================================================================
24 */
25public class StringYeniMetotlar {
26
27 public static void main(String[] args) {
28
29 // ====================================================================
30 // 1) strip() vs trim() - EN ONEMLI FARK: UNICODE!
31 // ====================================================================
32 //
33 // NEDIR: strip() bir String'in basindaki ve sonundaki bosluklari siler.
34 //
35 // NEDEN GELDI: Eski trim() metodu 1997'den beri var ama bir SORUNU var:
36 // trim() yalnizca kod degeri <= U+0020 (space) olan karakterleri siler.
37 // Yani bazi Unicode bosluk karakterlerini (orn. U+2007, U+00A0 - non
38 // breaking space, U+2003 - em space) TANIMAZ ve SILMEZ.
39 // strip() ise Character.isWhitespace() kullanir; tum Unicode bosluk
40 // karakterlerini dogru sekilde temizler.
41 //
42 System.out.println("=== 1) strip vs trim (Unicode) ===");
43
44 // U+2003 (EM SPACE) ile cevrelenmis metin - trim bunu SILEMEZ:
45 String unicodeBosluklu = " Merhaba ";
46
47 System.out.println("Orijinal uzunluk : " + unicodeBosluklu.length());
48 System.out.println("trim() sonrasi uzunluk: " + unicodeBosluklu.trim().length()
49 + " (trim Unicode bosluk siremedi!)");
50 System.out.println("strip() sonrasi uzunluk: " + unicodeBosluklu.strip().length()
51 + " (strip dogru temizledi)");
52
53 // stripLeading(): sadece bastaki, stripTrailing(): sadece sondaki
54 String veri = " sadece kenarlar ";
55 System.out.println("stripLeading() : '" + veri.stripLeading() + "'");
56 System.out.println("stripTrailing(): '" + veri.stripTrailing() + "'");
57 System.out.println("strip() : '" + veri.strip() + "'");
58
59 // ESKI YONTEM: trim() (Unicode-guvensiz) veya replaceAll regex:
60 // String s = veri.replaceAll("^\\s+|\\s+$", ""); // karmasik regex
61 // YENI YONTEM: veri.strip(); // temiz ve Unicode-dogru
62
63 // ====================================================================
64 // 2) isBlank() - bos VEYA sadece bosluk mu?
65 // ====================================================================
66 //
67 // NEDIR: String bos ("") veya yalnizca bosluk karakterlerinden mi
68 // olusuyor kontrol eder.
69 // NEDEN GELDI: isEmpty() sadece "" (sifir uzunluk) kontrol eder; icinde
70 // bosluk olan " " icin false doner. Form validasyonunda bu sorun.
71 //
72 System.out.println("\n=== 2) isBlank ===");
73 String bosluklu = " \t \n ";
74 System.out.println("isEmpty(): " + bosluklu.isEmpty()
75 + " (false - icinde bosluk var)");
76 System.out.println("isBlank(): " + bosluklu.isBlank()
77 + " (true - hepsi bosluk)");
78
79 // GERCEK HAYAT: form alani gercekten dolu mu?
80 String kullaniciGirdisi = " ";
81 if (kullaniciGirdisi.isBlank()) {
82 System.out.println("HATA: Isim alani bos birakilamaz!");
83 }
84 // ESKI YONTEM: if (s == null || s.trim().isEmpty()) { ... }
85 // YENI YONTEM: if (s.isBlank()) { ... }
86
87 // ====================================================================
88 // 3) lines() - cok satirli metni Stream<String> olarak gez
89 // ====================================================================
90 //
91 // NEDIR: Cok satirli bir String'i, satir sonlarina gore bolup
92 // Stream<String> dondurur. \n, \r, \r\n hepsini tanir.
93 // NEDEN GELDI: Eskiden split("\n") ile bolerdik ama \r\n (Windows)
94 // ve platform farkliliklari sorun cikariyordu. lines() bunlari
95 // dogru ele alir ve tembel (lazy) bir stream verir.
96 //
97 System.out.println("\n=== 3) lines ===");
98 String logMetni = "INFO: baslangic\nWARN: dikkat\nERROR: hata olustu\nINFO: bitis";
99
100 System.out.println("Toplam satir sayisi: " + logMetni.lines().count());
101 System.out.println("Sadece ERROR satirlari:");
102 logMetni.lines()
103 .filter(satir -> satir.startsWith("ERROR"))
104 .forEach(satir -> System.out.println(" >> " + satir));
105
106 // ESKI YONTEM: String[] satirlar = logMetni.split("\\r?\\n");
107 // YENI YONTEM: logMetni.lines() // stream olarak, lazy, dogru
108
109 // ====================================================================
110 // 4) repeat(int) - String'i N kez tekrarla
111 // ====================================================================
112 //
113 // NEDIR: String'i belirtilen sayida tekrarlayip yeni String dondurur.
114 // NEDEN GELDI: Eskiden bir karakteri/metni N kez tekrarlamak icin dongu
115 // veya StringBuilder yazmak gerekirdi. Cok yaygin bir ihtiyac.
116 //
117 System.out.println("\n=== 4) repeat ===");
118 System.out.println("=".repeat(40)); // 40 karakterlik cizgi
119 System.out.println("Ya" + "ha ".repeat(3));
120 System.out.println("Girinti:" + " ".repeat(4) + "(4 bosluk girinti)");
121
122 // GERCEK HAYAT: konsol tablosu/rapor basligi cizmek
123 String baslik = "RAPOR";
124 System.out.println("+" + "-".repeat(baslik.length() + 2) + "+");
125 System.out.println("| " + baslik + " |");
126 System.out.println("+" + "-".repeat(baslik.length() + 2) + "+");
127
128 // ESKI YONTEM:
129 // StringBuilder sb = new StringBuilder();
130 // for (int i = 0; i < 40; i++) sb.append("=");
131 // String cizgi = sb.toString();
132 // YENI YONTEM: "=".repeat(40);
133
134 // ====================================================================
135 // 5) Collection.toArray(IntFunction) - BONUS Java 11 yeniligi
136 // ====================================================================
137 //
138 // NEDIR: Bir koleksiyonu tipli diziye cevirirken artik bos dizi
139 // olusturup gecmek yerine, method reference verebiliriz.
140 //
141 System.out.println("\n=== 5) Collection.toArray(IntFunction) ===");
142 List<String> isimler = List.of("Ali", "Veli", "Ayse");
143
144 // YENI (Java 11): method reference ile temiz
145 String[] dizi = isimler.toArray(String[]::new);
146 System.out.println("Diziye cevrildi: " + String.join(", ", dizi));
147
148 // ESKI YONTEM: isimler.toArray(new String[0]); // veya new String[size]
149
150 // Birlestirilmis ornek: temizle + tekrarsiz + diziye al
151 List<String> temizlenmis = List.of(" Ali ", "Veli", " Ayse ").stream()
152 .map(String::strip)
153 .filter(s -> !s.isBlank())
154 .collect(Collectors.toList());
155 String[] sonDizi = temizlenmis.toArray(String[]::new);
156 System.out.println("Temizlenmis dizi: " + String.join(" | ", sonDizi));
157 }
158}TekDosyaCalistirma
çalıştırılabilir1import java.time.LocalDate;
2import java.util.List;
3import java.util.stream.Collectors;
4
5/**
6 * ============================================================================
7 * JAVA 11 - TEK DOSYA KAYNAK KODU CALISTIRMA - JEP 330
8 * (Launch Single-File Source-Code Programs)
9 * ============================================================================
10 *
11 * NEDIR?
12 * ------
13 * Java 11'den itibaren bir .java dosyasini ONCEDEN DERLEMEDEN (javac
14 * calistirmadan) DOGRUDAN calistirabiliriz:
15 *
16 * java TekDosyaCalistirma.java
17 *
18 * Bu komut dosyayi BELLEKTE derler ve hemen calistirir. Disk'e .class
19 * dosyasi YAZMAZ. Yani tek adimda kaynak kodu -> calisan program.
20 *
21 * NEDEN GELDI? (Hangi problem?)
22 * -----------------------------
23 * Java'ya yeni baslayanlar ve hizli deneme yapmak isteyenler icin iki adimli
24 * surec (once javac, sonra java) gereksiz bir engeldi:
25 * $ javac Merhaba.java # derle -> Merhaba.class olusur
26 * $ java Merhaba # calistir
27 * Python/Ruby gibi "yaz-calistir" dillerine kiyasla bu fazladan adim,
28 * ozellikle ogrenme ve kucuk script'lerde zaman kaybiydi. JEP 330 bunu
29 * tek adima indirdi.
30 *
31 * NE ISE YARAR / NEREDE KOLAYLIK SAGLAR?
32 * --------------------------------------
33 * - OGRENME: Yeni baslayanlar derleme detayina takilmaz.
34 * - HIZLI PROTOTIPLEME: Kucuk bir fikri saniyeler icinde dener.
35 * - SCRIPT YAZMA: Java'yi shell script gibi kullanabiliriz (shebang ile).
36 * - DENEME/TEST: Bir API'yi hizlica denemek icin gecici dosya.
37 *
38 * NASIL CALISTIRILIR?
39 * -------------------
40 * java TekDosyaCalistirma.java
41 * java TekDosyaCalistirma.java arg1 arg2 # argumanlarla
42 *
43 * GERCEK HAYAT ORNEGI:
44 * --------------------
45 * Bir gelistirici, "su tarih formatlama mantigi dogru calisiyor mu?" diye
46 * merak eder. Yeni bir proje acmak, IDE baslatmak yerine 20 satirlik bir
47 * .java dosyasi yazip 'java Test.java' ile aninda gorur.
48 * ============================================================================
49 */
50public class TekDosyaCalistirma {
51
52 public static void main(String[] args) {
53 System.out.println("===========================================");
54 System.out.println(" Java 11 Tek Dosya Calistirma (JEP 330)");
55 System.out.println("===========================================");
56 System.out.println("Bu program 'java TekDosyaCalistirma.java' ile");
57 System.out.println("ONCEDEN DERLENMEDEN dogrudan calistirilabilir!");
58 System.out.println("Bugunun tarihi: " + LocalDate.now());
59
60 // Komut satiri argumanlarini da kullanabiliriz:
61 if (args.length > 0) {
62 System.out.println("\nVerilen argumanlar:");
63 for (int i = 0; i < args.length; i++) {
64 System.out.println(" arg[" + i + "] = " + args[i]);
65 }
66 } else {
67 System.out.println("\n(Arguman verilmedi. Deneyin: "
68 + "java TekDosyaCalistirma.java Ahmet 42)");
69 }
70
71 // Java 11 ozelliklerini birlikte gosterelim:
72 List<String> isimler = List.of(" ali ", "veli", " ", "ayse ");
73 String temiz = isimler.stream()
74 .map(String::strip) // Java 11 strip()
75 .filter(s -> !s.isBlank()) // Java 11 isBlank()
76 .map(String::toUpperCase)
77 .collect(Collectors.joining(", "));
78 System.out.println("\nTemizlenmis isimler: " + temiz);
79 System.out.println("\nProgram tek dosya olarak basariyla calisti!");
80 }
81}
82
83/*
84 * ============================================================================
85 * ESKI YONTEM vs YENI YONTEM
86 * ============================================================================
87 *
88 * --- ESKI (Java 11 ONCESI): IKI ADIM ---
89 * $ javac TekDosyaCalistirma.java # 1. Derle (.class olusur)
90 * $ java TekDosyaCalistirma # 2. Calistir
91 * Dezavantaj: disk'e .class dosyasi yazilir, iki komut gerekir.
92 *
93 * --- YENI (Java 11): TEK ADIM ---
94 * $ java TekDosyaCalistirma.java # Bellekte derle + calistir
95 * Avantaj: tek komut, disk'e .class yazilmaz, hizli.
96 *
97 * NOT: .java uzantisini YAZMAK onemlidir. 'java TekDosyaCalistirma.java'
98 * (uzantili) -> kaynak kodu modu. 'java TekDosyaCalistirma' (uzantisiz)
99 * -> onceden derlenmis .class arar.
100 *
101 * ============================================================================
102 * SHEBANG (#!) ILE SCRIPT OLARAK CALISTIRMA
103 * ============================================================================
104 *
105 * JEP 330 ayrica Java dosyalarini Unix/Linux/macOS'ta SCRIPT gibi
106 * calistirmaya izin verir. Bunun icin:
107 *
108 * 1) Dosyanin ILK SATIRINA shebang eklenir (uzanti .java OLMAMALI, orn:
109 * "merhaba" gibi uzantisiz bir dosya):
110 *
111 * #!/usr/bin/java --source 11
112 * public class Merhaba {
113 * public static void main(String[] args) {
114 * System.out.println("Merhaba script!");
115 * }
116 * }
117 *
118 * 2) Dosyaya calistirma izni verilir:
119 * $ chmod +x merhaba
120 *
121 * 3) Dogrudan calistirilir (sanki bash/python script'iymis gibi):
122 * $ ./merhaba
123 * Merhaba script!
124 *
125 * ONEMLI: Shebang kullanilan dosya .java UZANTILI OLAMAZ. Shebang yalnizca
126 * uzantisiz (veya .java disi) dosyalarda gecerlidir; .java dosyalari icin
127 * 'java X.java' komutu kullanilir. --source 11 ile hangi dil seviyesinde
128 * derlenecegi belirtilir.
129 *
130 * KISITLAMALAR:
131 * - Tek dosya: birden fazla kaynak dosyaya bagimli olamaz (sadece JDK +
132 * classpath'teki hazir kutuphaneler kullanilabilir).
133 * - Dosya icindeki ILK sinif main metodunu icermeli.
134 * - Buyuk projeler icin DEGIL; kucuk script/prototip icindir.
135 * ============================================================================
136 */VarLambdaParametre
çalıştırılabilir1import java.util.List;
2import java.util.function.BiFunction;
3import java.util.function.BinaryOperator;
4import java.util.stream.Collectors;
5
6/**
7 * ============================================================================
8 * JAVA 11 - LAMBDA PARAMETRELERINDE 'var' KULLANIMI - JEP 323
9 * ============================================================================
10 *
11 * NEDIR?
12 * ------
13 * Java 10 ile yerel degisken tip cikarimi (Local Variable Type Inference)
14 * geldi: "var x = 10;". ANCAK Java 10'da 'var' lambda parametrelerinde
15 * KULLANILAMIYORDU. Java 11 (JEP 323) bunu mumkun kildi:
16 * (var a, var b) -> a + b
17 *
18 * NEDEN GELDI? (Hangi problem cozuldu?)
19 * -------------------------------------
20 * Tek basina "lambda parametresine var yazmak" cok da kisaltma saglamaz;
21 * zaten implicit (tip yazmadan) lambda yazabiliyoruz: (a, b) -> a + b.
22 * ASIL FAYDA: lambda parametrelerine ANNOTATION (ek aciklama, orn. @NonNull)
23 * ekleyebilmek icin bir tipe ihtiyac vardir. 'var' bu tipi saglar:
24 * (@NonNull var a, @NonNull var b) -> a + b
25 * Eskiden annotation eklemek icin TAM tip yazmak zorundaydik:
26 * (@NonNull Integer a, @NonNull Integer b) -> a + b // uzun
27 * 'var' ile annotation'i tutuyoruz ama uzun tip adini yazmiyoruz.
28 * Ayrica tutarlilik saglar: artik 'var' her yerde (yerel, lambda) calisir.
29 *
30 * KURALLAR (cok onemli):
31 * ----------------------
32 * 1) YA HEPSI YA HICBIRI: Bir lambdada parametrelerin ya HEPSI 'var'
33 * olmali ya da HICBIRI. Karistirilamaz.
34 * GECERSIZ: (var a, b) -> ...
35 * GECERSIZ: (var a, Integer b) -> ... // var + explicit tip karisik
36 * GECERLI: (var a, var b) -> ...
37 * 2) PARANTEZ ZORUNLU: Tek parametre bile olsa parantez sart.
38 * GECERSIZ: var x -> x * 2
39 * GECERLI: (var x) -> x * 2
40 *
41 * GERCEK HAYAT ORNEGI:
42 * --------------------
43 * Null-safety annotation'lari (Checker Framework, Spring @NonNull) kullanan
44 * kurumsal projelerde, lambda parametrelerine de bu annotation'lari koyup
45 * statik analiz aracina "bu parametre null olamaz" demek icin idealdir.
46 * ============================================================================
47 */
48public class VarLambdaParametre {
49
50 public static void main(String[] args) {
51
52 // ====================================================================
53 // 1) Temel kullanim: (var a, var b) -> ...
54 // ====================================================================
55 System.out.println("=== 1) Temel var lambda ===");
56
57 // YENI (Java 11): var ile
58 BiFunction<Integer, Integer, Integer> topla = (var a, var b) -> a + b;
59 System.out.println("topla(3, 5) = " + topla.apply(3, 5));
60
61 // Bu YENI yontem, asagidaki ESKI yontemlerle ESDEGER:
62 // ESKI A (implicit): (a, b) -> a + b
63 // ESKI B (explicit): (Integer a, Integer b) -> a + b
64
65 // ====================================================================
66 // 2) Tek parametreyle - PARANTEZ ZORUNLU
67 // ====================================================================
68 System.out.println("\n=== 2) Tek parametre (parantez zorunlu) ===");
69 java.util.function.Function<String, String> buyut = (var s) -> s.toUpperCase();
70 System.out.println("buyut(\"merhaba\") = " + buyut.apply("merhaba"));
71 // DIKKAT: var s -> ... YAZILAMAZ (derlenmez). (var s) -> ... olmali.
72
73 // ====================================================================
74 // 3) Stream icinde var lambda (gercekci kullanim)
75 // ====================================================================
76 System.out.println("\n=== 3) Stream icinde var ===");
77 List<String> kelimeler = List.of("elma", "armut", "kiraz", "incir");
78
79 String sonuc = kelimeler.stream()
80 .map((var k) -> k.toUpperCase()) // var parametre
81 .filter((var k) -> k.length() > 4) // var parametre
82 .collect(Collectors.joining(", "));
83 System.out.println("Sonuc: " + sonuc);
84
85 // ====================================================================
86 // 4) ASIL FAYDA: annotation ekleme (yorum icinde)
87 // ====================================================================
88 // Eger projede bir @NonNull annotation'i olsaydi soyle yazabilirdik:
89 //
90 // BinaryOperator<Integer> carp =
91 // (@NonNull var x, @NonNull var y) -> x * y;
92 //
93 // Burada @NonNull ekleyebilmek icin bir tipe ihtiyac var; 'var' bunu
94 // saglar. Annotation'siz haliyle gosterelim:
95 BinaryOperator<Integer> carp = (var x, var y) -> x * y;
96 System.out.println("\n=== 4) Annotation hazirligi ===");
97 System.out.println("carp(4, 6) = " + carp.apply(4, 6));
98 System.out.println("(Gercekte: (@NonNull var x, @NonNull var y) -> x * y yazilabilir)");
99
100 // ====================================================================
101 // 5) GECERSIZ ORNEKLER (sadece yorum - DERLENMEZ!)
102 // ====================================================================
103 // BiFunction<Integer,Integer,Integer> kotu1 = (var a, b) -> a + b; // HATA: karisik
104 // BiFunction<Integer,Integer,Integer> kotu2 = (var a, Integer b) -> a+b; // HATA: var + tip
105 // Function<Integer,Integer> kotu3 = var x -> x * 2; // HATA: parantezsiz
106
107 System.out.println("\nProgram bitti.");
108 }
109}
110
111/*
112 * ============================================================================
113 * ESKI (Java 10) vs YENI (Java 11) OZET
114 * ============================================================================
115 * | Durum | Java 10 | Java 11 |
116 * |--------------------------------|----------------|---------------|
117 * | var yerel degisken | VAR | VAR |
118 * | var lambda parametresi | YOK (hata) | VAR |
119 * | lambda parametresine annotation| tam tip lazim | var + annot. |
120 *
121 * Java 10: (a, b) -> a + b // var YAZILAMAZ
122 * Java 11: (var a, var b) -> a + b // var YAZILABILIR
123 * ============================================================================
124 */