Java 9, Java 8’in sunduğu fonksiyonel programlama, Lambda, Stream, Date-Time API gibi büyük yeniliklerin üzerine; mimari temizleme, modüler yapı, API kullanım kolaylığı ve dilsel küçük ama etkili iyileştirmeler getiriyor. Eğer hâlâ Java 8 kullanıyorsan, bazı projelerde Java 9’a geçmek kodlarının daha temiz, bakımı daha kolay ve mimarisi daha sürdürülebilir olmasını sağlayabilir.
Java 9 ile Gelen Özellikler
- Modüler Sistem – Java Platform Module System (JPMS)
- JShell – REPL (Read–Eval–Print Loop)
- Immutable Collection’lar için Factory Metotları
- Dil (Language) Geliştirmeleri
- Stream & Optional API’deki Geliştirmeler
- Process API Geliştirmeleri
Modüler Sistem – Java Platform Module System (JPMS)
Java 9, kodun modüllere ayrılmasını sağlayan bir modüler sistem getiriyor. JDK da modüller hâline geldi; hangi modülün hangi modüllere bağımlı olduğu (requires
), hangi paketlerin dışa açıldığı (exports
), hangi modüllerin erişimine kapalı olduğu gibi sınırlar netleşti. Böylece uygulamalar ve JDK kendisi daha güvenli, daha yönetilebilir ve daha hafif yapılara sahip olabiliyor.
module-info.java
dosyası şöyle olabilir:
module com.example.myapp {
requires java.sql; // bu modül java.sql modülüne ihtiyaç duyar
exports com.example.myapp.api; // bu paketi dışarı açar
}
Bir başka modül:
module com.example.db {
exports com.example.db.impl; // iç implementasyonu dışa sunar
}
Kullanım:
javac --module-source-path src -d out $(find src -name "*.java")
java --module-path out --module com.example.myapp/com.example.myapp.Main
JShell – REPL (Read–Eval–Print Loop)
Java artık etkileşimli bir kabuk (REPL) ortamına sahip. Küçük kod parçalarını doğrudan çalıştırmak, fikirleri hızlıca test etmek ya da sınıf/method yazmadan denemeler yapmak için çok kullanışlı.
jshell> int x = 5 * 7
x ==> 35
jshell> String s = "Merhaba Java 9"
s ==> "Merhaba Java 9"
jshell> s.substring(8)
$3 ==> "Java 9"
Immutable Collection’lar için Factory Metotları
Java 8’de immutable koleksiyon oluşturmak için Collections.unmodifiableList(...)
gibi daha dolaylı yollar kullanılıyordu. Java 9’da List.of(...)
, Set.of(...)
, Map.of(...)
, Map.ofEntries(...)
gibi metodlarla daha kısa ve temiz immutable koleksiyonlar oluşturmak mümkün.
import java.util.List;
import java.util.Set;
import java.util.Map;
public class ImmutableCollectionsExample {
public static void main(String[] args) {
List<String> liste = List.of("elma", "armut", "muz");
// liste.add("kiraz"); // UnsupportedOperationException
Set<Integer> set = Set.of(1, 2, 3, 4);
Map<String, Integer> map = Map.of(
"bir", 1,
"iki", 2,
"üç", 3
);
System.out.println(liste);
System.out.println(set);
System.out.println(map);
}
}
Dil (Language) Geliştirmeleri
Aşağıdakiler kod okunabilirliği, yeniden kullanım ve kodun daha temiz olması açısından önemli değişiklikler:
- 👉 Interface’lerde Private Metotlar
Default metodlar içinde ortak işler varsa bunları private metodlarla soyutlayıp kod tekrarını azaltmak mümkün. Ayrıca static private metodlar da var.
public interface Hesaplama {
default int toplama(int a, int b) {
validate(a, b);
return a + b;
}
default int carpma(int a, int b) {
validate(a, b);
return a * b;
}
private void validate(int a, int b) {
if (a < 0 || b < 0) {
throw new IllegalArgumentException("Negatif değer olamaz");
}
}
}
- 👉 Try-with-resources İyileştirmesi
Java 9’dan önce her kaynak (resource) için try parantezleri içinde yeni değişken oluşturmak gerekiyordu. Java 9 ile, kaynak olarak kullanılacak nesne final ya da effectively final ise doğrudan kullanılabiliyor.
class Kaynak implements AutoCloseable {
public void close() {
System.out.println("Kaynak kapatıldı");
}
public void doWork() {
System.out.println("İş yapılıyor");
}
}
public class TryWithResourcesExample {
public static void main(String[] args) {
Kaynak k = new Kaynak();
try (k) {
k.doWork();
}
}
}
- 👉 Diamond Operatörü Anonim Sınıflarla Kullanımı
Anonim (anonymous) inner class’larda diamond (<>
) operatörü kullanılabiliyor hale geldi. Bu, generics kullanımında kodu biraz kısaltıyor.
import java.util.Comparator;
public class DiamondAnonymousExample {
Comparator<String> cmp = new Comparator<>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
};
}
Stream & Optional API’deki Geliştirmeler
Java 9, Stream ve Optional sınıflarında bazı yeni metodlar getirerek işlevselliği artırdı.
- 👉 Stream API:
takeWhile
,dropWhile
,ofNullable
,iterate
’in yeni overload’ları gibi. - 👉 Optional:
ifPresentOrElse()
,or()
gibi yeni metodlarla, Optional değerleriyle çalışmak daha esnek hâle geldi.
import java.util.*;
import java.util.stream.*;
public class StreamOptionalExample {
public static void main(String[] args) {
// Stream.takeWhile / dropWhile
Stream<Integer> seq = Stream.of(1, 2, 3, 4, 5, 6);
seq.takeWhile(n -> n <= 3)
.forEach(n -> System.out.println("takeWhile: " + n));
seq = Stream.of(1, 2, 3, 4, 5, 6);
seq.dropWhile(n -> n <= 3)
.forEach(n -> System.out.println("dropWhile: " + n));
// ofNullable
Stream<String> maybe = Stream.ofNullable(null);
System.out.println("maybe count: " + maybe.count());
// Optional
Optional<String> opt = Optional.of("Java9");
opt.ifPresentOrElse(
s -> System.out.println("Var: " + s),
() -> System.out.println("Yok!")
);
Optional<String> fallback = opt.or(() -> Optional.of("Varsa fallback"));
System.out.println("or() sonucu: " + fallback.get());
}
}
Process API Geliştirmeleri
Java 9 ile işletim sistemi süreçleri (processes) ile ilgili daha detaylı kontrol ve bilgilere erişim sağlanıyor. Örneğin:
- 👉 Mevcut sürecin PID’si alınabiliyor.
- 👉 Başlangıç zamanı, CPU süresi gibi bilgiler
ProcessHandle
üzerinden okunabiliyor. - 👉
children()
vedescendants()
metodları ile alt süreçler/fonksiyon çağrıları takip edilebiliyor.
import java.time.Duration;
import java.time.Instant;
public class ProcessApiExample {
public static void main(String[] args) {
ProcessHandle current = ProcessHandle.current();
long pid = current.pid();
ProcessHandle.Info info = current.info();
System.out.println("PID: " + pid);
info.startInstant().ifPresent(start -> System.out.println("Başlangıç: " + start));
info.totalCpuDuration().ifPresent(cpu -> System.out.println("CPU süresi: " + cpu));
// Alt süreçler
current.children().forEach(child ->
System.out.println("Child process ID: " + child.pid())
);
}
}
👉 Sıradaki yazımızda Java 9 ile gelen Modüler Sistem ve diğer yeniliklere göz atacağız:
➡️ Java 10 – Local Variable Type Inference (var
)
📝 Kaynaklar:
- https://www.oracle.com/java/technologies/javase/9-relnotes.html
- https://www.baeldung.com/new-java-9
- https://www.digitalocean.com/community/tutorials/java-9-features-with-examples
- https://www.geeksforgeeks.org/java/java-9-features-with-examples/
- https://beginnersbook.com/2018/04/java-9-features-with-examples/
- https://www.tutorialspoint.com/java/java9_new_features.htm
- https://www.tothenew.com/blog/exploring-java-9-to-17-features/