Java 18 (Mart 2022)
| Özellik | Değer | |---|---| | Sürüm | Java 18 (JDK 18) | | Çıkış Tarihi | 22 Mart 2022 | | Destek Türü | Feature Release (kısa vadeli, LTS DEĞİL) | | LTS mı? | Hayır. Sonraki LTS Java 21'dir (Eylül 2023). | | Önceki…
Java 18 (Mart 2022)
Sürüm Bilgileri
| Özellik | Değer |
|---|---|
| Sürüm | Java 18 (JDK 18) |
| Çıkış Tarihi | 22 Mart 2022 |
| Destek Türü | Feature Release (kısa vadeli, LTS DEĞİL) |
| LTS mı? | Hayır. Sonraki LTS Java 21'dir (Eylül 2023). |
| Önceki LTS | Java 17 (Eylül 2021) |
| JEP Sayısı | 9 JEP |
Önemli Not: Java 18 bir "ara sürümdür". Üretim sistemlerinde nadiren doğrudan hedeflenir; çünkü 6 ayda bir gelen feature release'lerin desteği yalnızca bir sonraki sürüme kadar (6 ay) sürer. Buna rağmen Java 18, daha sonra Java 21 LTS'te kalıcı hale gelecek özelliklerin (Pattern Matching for switch, Foreign Function & Memory API) olgunlaşma yolundaki önemli bir basamağıdır.
Genel Bakış
Java 18, görece "sakin" bir sürüm olmakla birlikte, gündelik geliştiriciyi doğrudan etkileyen çok kritik bir değişiklik getirdi: UTF-8'in tüm platformlarda varsayılan karakter kodlaması olması. Bu, yıllardır süren "Windows'ta çalışıyor, Linux'ta bozuk karakter" sınıfı hataların kökünü kurutan bir adımdır.
Bu sürümün kapsadığı başlıca özellikler:
- JEP 400 — UTF-8 by Default (KALICI): Varsayılan charset artık platformdan bağımsız UTF-8.
- JEP 408 — Simple Web Server (KALICI):
jwebserverkomutu ile tek satırda statik dosya sunucusu. - JEP 413 — Code Snippets in Java API Documentation: Javadoc içinde
@snippetetiketi. - JEP 420 — Pattern Matching for switch (İkinci Preview):
switchifadelerinde desen eşleştirme. - JEP 419 — Foreign Function & Memory API (İkinci Incubator): JNI'nin modern halefi.
- JEP 417 — Vector API (Üçüncü Incubator): SIMD donanım hızlandırma.
- JEP 416 — Reimplement Core Reflection with Method Handles: İçsel iyileştirme.
- JEP 418 — Internet-Address Resolution SPI: DNS çözümleme için eklenebilir servis.
Özellik Detayları
1. UTF-8 Varsayılan Charset (JEP 400) — KALICI
İlgili dosya:
UTF8Varsayilan.java
NEDİR?
Java'da new FileReader(...), new String(byte[]), PrintStream gibi pek çok API açıkça bir charset verilmediğinde "varsayılan charset"i kullanır. Java 17 ve öncesinde bu varsayılan, işletim sisteminin ve bölge ayarının (locale) belirlediği bir değerdi:
- Windows (Türkçe):
windows-1254veyaCp1252 - Linux/macOS (modern): genellikle
UTF-8
Java 18 ile file.encoding sistem özelliği belirtilmediğinde varsayılan her platformda UTF-8 olur.
NEDEN GELDİ?
Onlarca yıllık "benim makinemde çalışıyor" probleminin temel kaynaklarından biriydi. Bir geliştirici UTF-8 makinede yazdığı dosyayı, başka bölge ayarına sahip bir sunucuda okuduğunda Türkçe karakterler (ç, ğ, ş, ü, ö, ı) bozuluyordu. Sorun sinsiydi: kod doğru görünüyor ama çıktı ortama göre değişiyordu.
NE İŞE YARAR / NEREDE KOLAYLIK SAĞLAR?
- Aynı kod, geliştirme makinesinde de CI sunucusunda da üretim sunucusunda da aynı sonucu üretir.
- Charset'i her yerde elle belirtme zorunluluğu pratikte ortadan kalkar (ama yine de en iyi pratik açıkça belirtmektir).
- Türkçe gibi ASCII dışı karakter içeren diller için davranış öngörülebilir hale gelir.
ESKİ vs YENİ
// ESKİ (Java 17 ve öncesi) — RİSKLİ: charset platforma bağlı try (FileReader fr = new FileReader("veri.txt")) { ... } // Windows-TR: Cp1254, Linux: UTF-8 -> aynı dosya farklı okunur! // YENİ (Java 18+) — varsayılan her yerde UTF-8 try (FileReader fr = new FileReader("veri.txt")) { ... } // Her platformda UTF-8 // EN İYİ PRATİK (her sürümde güvenli) — charset'i açıkça belirt import java.nio.charset.StandardCharsets; Files.readString(Path.of("veri.txt"), StandardCharsets.UTF_8);
GERÇEK HAYAT ÖRNEĞİ
Bir e-ticaret ekibi, ürün açıklamalarını CSV'den içe aktaran bir batch işi yazar. Geliştirici (Mac, UTF-8) testlerde sorun görmez. Üretim sunucusu (eski Windows Server, Cp1254) dosyayı içe aktarınca "Büyük Çığlık" ürünü veritabanına "Büyük Çýglýk" olarak yazılır. Java 18 ile her iki ortam da UTF-8 kullandığından bu sınıf hata kaybolur.
AVANTAJ / DEZAVANTAJ / RİSK
- Avantaj: Taşınabilirlik, öngörülebilirlik, Türkçe içerikte güvenlik.
- Risk (Geçişte): Eski sistemler, üretilen dosyaların önceki platform charset'i (örn. Cp1254) ile okunmasına bel bağlamış olabilir. Java 18'e geçince eski araçlar bu dosyaları yanlış okuyabilir. Geçici çözüm:
-Dfile.encoding=COMPATveya açık charset. - Tespit:
System.out.println(Charset.defaultCharset())çıktısını sürüm geçişinden önce/sonra karşılaştırın.
2. Simple Web Server (JEP 408) — KALICI
Detaylı anlatım:
SimpleWebServer.md
NEDİR?
JDK ile birlikte gelen jwebserver komut satırı aracı ve com.sun.net.httpserver paketindeki programatik API. Tek bir komutla, içinde bulunduğunuz dizini statik dosya sunucusu olarak yayınlar.
NEDEN GELDİ?
Geliştiriciler hızlı bir statik dosya sunucusu için çoğu zaman Python'un python -m http.server'ına başvuruyordu. Java ekosisteminde böyle "pil dahil" bir araç yoktu. Eğitim, prototipleme, test ve geçici dosya paylaşımı senaryoları için hafif bir çözüm gerekiyordu.
NE İŞE YARAR?
- Statik HTML/CSS/JS prototiplerini saniyeler içinde yayınlamak.
- Bir REST istemcisini test ederken sahte (mock) dosyalar sunmak.
- Eğitimde HTTP kavramlarını göstermek.
ESKİ vs YENİ
# ESKİ: Python'a bağımlılık veya tam teşekküllü bir sunucu yazmak python3 -m http.server 8000 # YENİ (Java 18+): JDK içinde gelir jwebserver -p 8000
GERÇEK HAYAT ÖRNEĞİ
Bir frontend ekibi, build edilmiş statik dosyaları (dist/ klasörü) hızlıca bir test cihazında göstermek ister. jwebserver -b 0.0.0.0 -p 8080 ile dosyalar anında ağ üzerinden erişilebilir.
NOT
Üretim için TASARLANMAMIŞTIR: sadece GET ve HEAD destekler, HTTPS yoktur, kimlik doğrulama yoktur. Yalnızca geliştirme/test içindir.
3. Code Snippets in Java API Documentation (JEP 413)
NEDİR?
Javadoc içinde @snippet etiketi ile kod örneklerini gömme imkanı. Eski <pre>{@code ...}</pre> yönteminin modern, doğrulanabilir ve sözdizimi vurgulu halefi.
NEDEN GELDİ?
Javadoc içindeki kod örnekleri "ölü metin"di: derlenmez, vurgulanmaz, harici dosyadan alınamazdı. Bu yüzden dokümandaki örnekler kolayca eskir ve hatalı hale gelirdi.
ESKİ vs YENİ
// ESKİ /** * <pre>{@code * List<String> liste = List.of("a", "b"); * }</pre> */ // YENİ (Java 18+) — doğrulanabilir, vurgulanır, harici dosyadan alınabilir /** * {@snippet : * List<String> liste = List.of("a", "b"); // @highlight substring="of" * } */
NEREDE KOLAYLIK SAĞLAR?
Kütüphane yazarları için: örnek kodlar gerçek kaynak dosyalardan çekilebildiğinden, örnekler her zaman derlenir ve güncel kalır.
4. Pattern Matching for switch (JEP 420) — İKİNCİ PREVIEW
NEDİR?
switch ifadelerinde tür deseni (type pattern) eşleştirme. Java 17'deki ilk preview'in geliştirilmiş hali.
EVRİM (ÇOK ÖNEMLİ)
Bu özellik bir evrim hikayesinin parçasıdır:
- Java 17: 1. preview (JEP 406)
- Java 18: 2. preview (JEP 420) — guarded pattern sözdizimi
&&yerinewhenolarak değişti - Java 19: 3. preview (JEP 427)
- Java 20: 4. preview (JEP 433)
- Java 21: KALICI (JEP 441)
ESKİ vs YENİ
// ESKİ String tanim; if (nesne instanceof Integer i) tanim = "tam sayı: " + i; else if (nesne instanceof String s) tanim = "metin: " + s; else tanim = "bilinmeyen"; // YENİ (preview) String tanim = switch (nesne) { case Integer i -> "tam sayı: " + i; case String s -> "metin: " + s; default -> "bilinmeyen"; };
Tam ve kalıcı kullanım örneği için Java 21 klasöründeki
PatternMatchingSwitchKalici.javadosyasına bakın.
5. Foreign Function & Memory API (JEP 419) — İKİNCİ INCUBATOR
NEDİR?
JVM dışındaki yerel (native) kod ve bellekle güvenli, performanslı etkileşim. Eski JNI'nin (Java Native Interface) modern, daha güvenli halefi.
NEDEN GELDİ?
JNI kırılgan, hataya açık ve yazması zordu. C kütüphanelerini (örn. OpenSSL, SQLite, makine öğrenmesi kütüphaneleri) çağırmak büyük zahmet gerektiriyordu.
EVRİM
- Java 14-17: Incubator (Foreign Memory)
- Java 18: 2. incubator
- Java 19: Preview
- Java 21: 3. preview (JEP 442)
- Java 22: KALICI (JEP 454)
Bu özellik Java 18'de hâlâ incubator olduğundan örnek dosya eklenmemiştir; kalıcı haline ulaşması Java 22'yi bulmuştur.
6. Vector API (JEP 417) — ÜÇÜNCÜ INCUBATOR
NEDİR?
Hesaplamaları modern CPU'ların SIMD (Single Instruction, Multiple Data) komutlarına derleyen bir API. Örneğin iki dizinin elemanlarını tek seferde paralel toplamak.
NEREDE KOLAYLIK SAĞLAR?
Bilimsel hesaplama, makine öğrenmesi, görüntü işleme, finansal modelleme gibi sayısal yoğun işlerde önemli hız artışı.
Geçiş Rehberi: Java 17 -> Java 18'de Ne Değişti?
| Konu | Etki | Önerilen Aksiyon |
|---|---|---|
| UTF-8 varsayılan | Dosya/akış okuma davranışı değişebilir | Charset'i her zaman açıkça belirtin; Charset.defaultCharset() çıktısını test edin |
jwebserver | Yeni araç | Geliştirme/test akışına dahil edilebilir |
| Pattern matching switch | Hâlâ preview | Üretimde kullanmayın; --enable-preview gerektirir |
| FFM & Vector API | Incubator | API'ler değişebilir; üretim için erken |
Genel Tavsiye
Java 18'i doğrudan üretim hedefi yapmak yerine, Java 17 LTS'ten Java 21 LTS'e geçerken yol üzerindeki bir öğrenme/test sürümü olarak değerlendirin. Java 18'in en kalıcı mirası UTF-8 varsayılanıdır.
▶ Kod Örnekleri(1)
UTF8Varsayilan
çalıştırılabilir1import java.io.IOException;
2import java.io.PrintWriter;
3import java.nio.charset.Charset;
4import java.nio.charset.StandardCharsets;
5import java.nio.file.Files;
6import java.nio.file.Path;
7
8/**
9 * JAVA 18 - UTF-8 VARSAYILAN CHARSET (JEP 400)
10 * ============================================
11 *
12 * Bu dosya, Java 18 ile gelen "UTF-8 by Default" degisikligini gosterir.
13 *
14 * NEDIR?
15 * Java 17 ve oncesinde, charset belirtilmeden yapilan dosya/akis islemleri
16 * isletim sisteminin "varsayilan charset"ini kullanirdi. Bu deger platforma
17 * ve bolge ayarina (locale) gore degisirdi:
18 * - Windows (Turkce): Cp1254 / windows-1254
19 * - Linux/macOS (modern): UTF-8
20 * Java 18 ile bu varsayilan HER PLATFORMDA UTF-8 oldu.
21 *
22 * NEDEN ONEMLI (TURKCE ICIN)?
23 * ç, ğ, ş, ü, ö, ı, İ gibi karakterler ASCII disindadir. Yanlis charset ile
24 * okunduklarinda bozulurlar ("Çığlık" -> "Çýglýk"). Java 18 bu sinifi
25 * ortadan kaldirir cunku her ortam ayni (UTF-8) varsayilani kullanir.
26 *
27 * DERLEME / CALISTIRMA:
28 * javac UTF8Varsayilan.java
29 * java UTF8Varsayilan
30 *
31 * (Preview ozellik DEGILDIR; --enable-preview gerektirmez.)
32 *
33 * Eski davranisi (geriye uyumluluk) test etmek icin:
34 * java -Dfile.encoding=Cp1254 UTF8Varsayilan
35 */
36public class UTF8Varsayilan {
37
38 public static void main(String[] args) throws IOException {
39
40 System.out.println("=== JAVA 18: UTF-8 VARSAYILAN CHARSET ===\n");
41
42 // 1) Mevcut varsayilan charset'i goster
43 // Java 18+ ile, file.encoding ozellikle ayarlanmadiysa bu UTF-8 doner.
44 Charset varsayilan = Charset.defaultCharset();
45 System.out.println("Bu JVM'in varsayilan charset'i : " + varsayilan);
46 System.out.println("file.encoding sistem ozelligi : "
47 + System.getProperty("file.encoding"));
48 System.out.println("native.encoding (OS charset'i) : "
49 + System.getProperty("native.encoding")); // Java 18'de eklendi
50 System.out.println();
51
52 if (varsayilan.equals(StandardCharsets.UTF_8)) {
53 System.out.println("-> Varsayilan UTF-8. Java 18+ tipik davranisi.\n");
54 } else {
55 System.out.println("-> Varsayilan UTF-8 DEGIL (" + varsayilan
56 + "). Muhtemelen -Dfile.encoding ile eski davranis zorlandi.\n");
57 }
58
59 // 2) Turkce icerikli bir dosya yazip okuyalim
60 Path dosya = Files.createTempFile("turkce-ornek", ".txt");
61 String turkceMetin = "Ürün: Büyük Çığlık — Şehir İstanbul, fiyat 1.299₺";
62
63 // ESKI YONTEM (RISKLI): charset belirtilmeden yazma/okuma.
64 // Java 17'de platforma bagliydi; Java 18'de her yerde UTF-8.
65 riskliYazVeOku(dosya, turkceMetin);
66
67 // EN IYI PRATIK: charset'i HER ZAMAN acikca belirt (her surumde guvenli)
68 guvenliYazVeOku(dosya, turkceMetin);
69
70 // Temizlik
71 Files.deleteIfExists(dosya);
72
73 // 3) Ozet ve gecis uyarisi
74 ozetVeUyari();
75 }
76
77 /**
78 * Charset belirtmeden yazip okur.
79 * Java 18+ ile artik her platformda UTF-8 oldugu icin guvenlidir,
80 * ANCAK eski JVM'lerde veya -Dfile.encoding ile zorlandiginda bozulabilir.
81 */
82 private static void riskliYazVeOku(Path dosya, String metin) throws IOException {
83 System.out.println("--- Yontem 1: Charset BELIRTILMEDEN (varsayilana guvenerek) ---");
84
85 // Charset'siz PrintWriter -> varsayilan charset kullanir
86 try (PrintWriter yazici = new PrintWriter(Files.newBufferedWriter(dosya))) {
87 yazici.println(metin);
88 }
89
90 // Charset'siz okuma -> yine varsayilan charset
91 String okunan = Files.readString(dosya).strip();
92 System.out.println("Yazilan : " + metin);
93 System.out.println("Okunan : " + okunan);
94 System.out.println("Eslesti mi? " + metin.equals(okunan));
95 System.out.println();
96 }
97
98 /**
99 * Charset'i acikca UTF-8 olarak belirtir. Hangi JVM/platform olursa olsun
100 * dogru calisir. ONERILEN yontem budur.
101 */
102 private static void guvenliYazVeOku(Path dosya, String metin) throws IOException {
103 System.out.println("--- Yontem 2: Charset ACIKCA UTF-8 (ONERILEN) ---");
104
105 Files.writeString(dosya, metin, StandardCharsets.UTF_8);
106 String okunan = Files.readString(dosya, StandardCharsets.UTF_8);
107
108 System.out.println("Yazilan : " + metin);
109 System.out.println("Okunan : " + okunan);
110 System.out.println("Eslesti mi? " + metin.equals(okunan));
111
112 // Byte seviyesinde de gosterelim: "ç" UTF-8'de 2 byte (0xC3 0xA7)
113 byte[] cBytes = "ç".getBytes(StandardCharsets.UTF_8);
114 System.out.print("'c' karakterinin UTF-8 byte'lari: ");
115 for (byte b : cBytes) {
116 System.out.printf("0x%02X ", b);
117 }
118 System.out.println("\n");
119 }
120
121 private static void ozetVeUyari() {
122 System.out.println("=== OZET ===");
123 System.out.println("""
124 * Java 18+ : varsayilan charset = UTF-8 (her platformda ayni).
125 * Avantaj : 'benim makinemde calisiyor' sinifi charset hatalari biter.
126 * Risk : Eski araclar uretilen dosyalari onceki OS charset'i ile
127 okumaya bel baglamis olabilir. Gecislerde dikkat!
128 * Tavsiye : Charset'i HER ZAMAN acikca belirtin (StandardCharsets.UTF_8).
129 Boylece kod hangi Java surumunde olursa olsun guvenli kalir.
130 * Geri uyum: Eski davranisi gecici olarak su sekilde zorlayabilirsiniz:
131 java -Dfile.encoding=Cp1254 SinifAdi
132 """);
133 }
134}