ANDROID PROGRAMLAMA

Android programlama dili paradigması Kotlin yeşil logosu ve Java turuncu logosu yan yana kıyaslama

"Android için hangi dil?" sorusu ilk bakışta basit görünür, cevabı da neredeyse refleks gibidir: Kotlin. Ama bu cevap sorunun yüzeyini sıyırır. Gerçek soru şu: Google 2019'da Kotlin'i "tercih edilen dil" ilan ettiğinde sadece bir favoriden mi söz ediyordu, yoksa Android'in geleceğini belirli bir dil paradigmasına mı bağlıyordu?

İkincisi. Kotlin sadece daha az kod yazdırdığı için tercih edilmedi; nesne yönelimli ve fonksiyonel paradigmaları aynı dilde harmanladığı, null güvenliğini tip sistemine işlediği ve coroutine üzerinden modern eşzamanlılığı dile yerleştirdiği için tercih edildi. Java hâlâ kullanılıyor — milyonlarca satırlık eski kod tabanı bir gecede silinmiyor. Ama yeni Android projesinde Kotlin seçmemenin somut bir teknik gerekçesi bulunmuyor. Aşağıda iki dilin farkını paradigma seviyesinde açtık; "hangisi daha popüler" değil, "hangisi ne yapar".

Android'de Hangi Diller Kullanılır?

Android Studio bir proje oluştururken size dil seçenekleri sunar ama listenin tamamı eşit ağırlıkta değil. Pratikte Android için programlama yaparken karşılaşacağınız diller belli bir hiyerarşiye oturur.

  • Kotlin: JetBrains tarafından geliştirilen, 2017'den beri resmi Android dili, 2019'dan beri Google'ın "preferred" tercihi. Yeni projelerin neredeyse tamamı buradan başlar.
  • Java: Android'in doğduğu dil. 2008'den 2017'ye kadar tek seçenekti. Milyonlarca satırlık eski uygulama hâlâ Java; bakım ve genişletme için bilinmesi gerekiyor.
  • C/C++ (NDK): Performans-kritik alt katman için (oyun motoru, kodek, görüntü işleme). Java/Kotlin tarafı ile JNI üzerinden konuşur. Tüm uygulamayı C++ ile yazmak istisna.
  • Dart (Flutter), JavaScript (React Native): Cross-platform framework dilleri. Native Android değil, ayrı bir kategori — runtime farklı.

Bu makalenin geri kalanı Kotlin ve Java üzerine çünkü "Android programlama" deyince gerçek seçim bu iki dil arasında olur. C++ ihtiyaca göre eklenen bir katman, cross-platform ise farklı bir karar.

Kotlin mi Java mı?

Soruyu net cevap vermek gerekirse: yeni Android projesi başlatıyorsanız Kotlin. Eski Java projesini sürdürüyorsanız Java bilmek zorundasınız, ama yeni modüllerinizi Kotlin yazabilirsiniz — iki dil aynı projede sorunsuz koşar.

Bu cevap fanatizm değil mühendislik tercihidir. Google'ın Android dökümantasyonu Kotlin-first yazılıyor; yeni Jetpack kütüphaneleri Kotlin idiomatik API'lerle geliyor; Coroutine, Flow, Compose gibi modern teknolojiler Kotlin için tasarlanıyor. Java tarafı geriye uyumlu kalsa da yeni API'lerin Java versiyonu çoğu zaman uzun ve hantal.

İstatistiklere göre 2024 itibarıyla Play Store'daki en popüler 1000 uygulamanın yaklaşık %95'i Kotlin içeriyor — tamamen Kotlin olmasa da en azından kısmi geçiş yapmış durumda. Mülakatlarda da artık Kotlin bilgisi varsayılan; Java sadece "legacy code'u okuyabilir misin" sorusunun cevabı.

Resmi açıklama için developer.android.com/kotlin sayfası Google'ın Kotlin-first stratejisini birinci ağızdan anlatır. Dilin kendi referans sitesi kotlinlang.org ise dil spesifikasyonu ve syntax kılavuzu için başvurulacak adres.

Kotlin ve Java dil özellikleri karşılaştırma diyagramı null safety data class coroutine extension function

Dil Paradigması Farkı

İki dilin görünür yüzünde syntax var; altında ise paradigma var. Asıl fark burada.

Java saf nesne yönelimli bir dildir. Her şey bir sınıfın içindedir; statik metotlar bile sınıfa bağlıdır. Fonksiyon kavramı dilin birinci sınıf vatandaşı değil — Java 8 ile lambda eklendi ama altında hâlâ functional interface (tek metotlu interface) çalışıyor. Java fonksiyonu bir nesneye dönüştürerek taklit eder; gerçek fonksiyonel programlama yapısı dil seviyesinde yok.

Kotlin ise çoklu paradigmalı bir dildir. Hem nesne yönelimini hem fonksiyonel programlamayı dilin temelinde tutar. Bu iki cümlede özetlenebilir gibi görünüyor ama pratikte büyük bir fark yaratıyor:

  • Fonksiyonlar birinci sınıf: Kotlin'de fonksiyon bir tiptir. Değişkene atanır, parametre olarak geçirilir, döndürülür. Sınıfa bağlı olmak zorunda değil — top-level fonksiyon yazılır.
  • İmmutable koleksiyonlar: Standart kütüphane List ve MutableList'i ayırır. Değiştirilemez veri yapısı default. Java'da ekstra wrapper gerekir.
  • Higher-order functions: map, filter, fold, reduce dilin kendi parçası. Stream API gibi ayrı bir kütüphaneye geçmek gerekmez.
  • Lambda ve closure: Kotlin lambdası dış scope'taki değişkene erişebilir ve değiştirebilir. Java lambdası "effectively final" zorunluluğu nedeniyle dışarıdaki değişkeni değiştiremez.
  • Sealed class ve when expression: Cebirsel veri tipi tarzı modelleme. Belirli bir set durumu tip sisteminde ifade eder; Java switch'i bu yetenekten yoksun.

Bu özellikler topluca Kotlin'i sadece "kısa Java" değil farklı bir dil yapar. Java OOP üzerine düşünmenizi gerektirirken, Kotlin ihtiyaca göre OOP ve fonksiyonel arası geçiş yapmanıza izin verir.

Null Safety Neden Önemli?

Tony Hoare null referansını "milyar dolarlık hata" olarak nitelendirir — kendisi 1965'te ALGOL'a eklediğine pişman olduğunu söyler. Java bu hatayı miras aldı; her referans default olarak null olabilir, NullPointerException Android uygulamalarındaki crash'lerin başlıca sebebidir.

Kotlin null'ı dilin tip sisteminin parçası yaptı. Bir String null olamaz; null olabilecek değer için String? yazmanız gerekir. Derleyici bu farkı zorunlu tutar:

// Java
String ad = veriCek();   // null dönebilir, derleyici uyarmaz
int uzunluk = ad.length(); // çalışma zamanında NPE riski

// Kotlin
val ad: String = veriCek()    // ? yoksa null dönerse derleme hatası
val uzunlukGuvenli = ad?.length ?: 0  // null ise 0 al

Bu sadece "daha güvenli" değil aynı zamanda "daha az defensif kod" anlamına da gelir. Java'da her parametre başında if (param == null) throw... yazmak alışkanlıktır; Kotlin'de derleyici bu kontrolü tip seviyesinde halletmiş olur. Android'de yıllık crash raporlarının önemli bölümünü NPE oluştururken Kotlin'e geçen ekipler bu rakamın belirgin düştüğünü raporlar.

Syntax ve Boilerplate

Aynı işi yapan Java ve Kotlin kodunu yan yana koyduğunuzda Kotlin yaklaşık üçte bir daha kısadır. Bu bir estetik mesele değil — uzun kod daha çok hata, daha zor okuma demektir. En tipik örnek data class:

// Java — yaklaşık 30 satır
public class Kullanici {
  private final String ad;
  private final int yas;
  public Kullanici(String ad, int yas) {
    this.ad = ad; this.yas = yas;
  }
  public String getAd() { return ad; }
  public int getYas() { return yas; }
  @Override public boolean equals(Object o) { /* ... */ }
  @Override public int hashCode() { /* ... */ }
  @Override public String toString() { /* ... */ }
}

// Kotlin — tek satır
data class Kullanici(val ad: String, val yas: Int)

Tek satır Kotlin kodu otomatik olarak constructor, getter'lar, equals(), hashCode(), toString() ve hatta copy() fonksiyonunu üretir. Java 14+ ile gelen record bu boşluğun bir kısmını kapatır ama Android'in minimum SDK desteği hâlâ Java records'u kullanmayı pratik kılmıyor.

Boilerplate azalmasının diğer kaynakları:

  • Tip çıkarımı: val sayi = 5 demek Int sayi = 5 demektir; tip yazmaya gerek yok.
  • Smart cast: is String kontrolünden sonra değişken otomatik String'e cast olur; ayrı satırda (String) x yazmazsınız.
  • Extension function: Mevcut sınıfa dışarıdan metot ekleme — Utility class ihtiyacını ortadan kaldırır.
  • String template: "Merhaba, ${ad}" şeklinde direkt interpolasyon; Java'daki String.format() veya concat zinciri yok.
  • Trailing lambda: Son parametresi lambda olan fonksiyon süslü parantez dışına çıkarılır; DSL tarzı okunabilir API'ler bu sayede mümkün.

Coroutine ve Eşzamanlılık

Android uygulamasında ağ çağrısı, veritabanı sorgusu, dosya okuma — hepsi ana iş parçacığını bloklarsa UI donar. Java tarafında bu iş AsyncTask (artık deprecated), Thread, ExecutorService, RxJava gibi katmanlarla çözüldü. Hepsinin ortak sorunu: callback hell ve karmaşık sentaks.

Kotlin Coroutine bu problemi dil seviyesinde çözer. suspend anahtar kelimesi bir fonksiyonun "askıya alınabilir" olduğunu belirtir; çağıran kod bloklanmaz ama sanki bloklanmış gibi sıralı yazılır:

// Coroutine ile — okunabilir, sıralı
suspend fun kullaniciYukle(id: Int): Kullanici {
  val profil = apiServis.profil(id)       // askıya alınır
  val siparis = apiServis.siparisler(id)  // askıya alınır
  return Kullanici(profil, siparis)
}

Aynı işi Java RxJava ile yazmak iç içe geçmiş flatMap ve subscribe zincirleri demek. Coroutine ayrıca Flow ile reaktif akış modelini, StateFlow ile UI state yönetimini, scope kavramı ile lifecycle bağlı işlemleri sade bir biçimde ifade eder.

Bu Android'de büyük avantajdır çünkü her ekran kendi yaşam döngüsüne sahip — Activity destroy olduğunda işin de iptal olması gerekir. Coroutine bunu viewModelScope ve lifecycleScope ile otomatik yapar; Java'da el ile yönetilen referans temizliği gerekir.

Kotlin coroutine asenkron akış suspend fonksiyon ve scope yönetimi şematik görselleştirme yeşil tonlu

Hangisi Ne Zaman Seçilir?

Tüm bu farklılıklar Kotlin'i tek doğru cevap yapmaz. Bazı senaryoda Java hâlâ tercih edilebilir veya zorunludur:

  • Yeni proje, sıfırdan Android uygulama: Kotlin. Başka bir cevabın gerekçesi yok.
  • Mevcut Java kod tabanı bakım: Java. Eski kodu Kotlin'e zorla çevirmek migrasyon riski yaratır; yeni modülleri Kotlin yazıp eskileri kademeli dönüştürün.
  • Ekipte Kotlin bilen yok: Java ile başlayıp paralel öğrenme. Java tarafı çalışırken Kotlin'e ısınma süresi 2-3 ay.
  • Kütüphane yazıyorsanız: Çift hedefli düşünün. Kotlin yazın ama Java tarafından çağrılabilirliği @JvmStatic, @JvmOverloads gibi anotasyonlarla koruyun.
  • Android-only değil cross-platform hedefiniz var: Kotlin Multiplatform (KMP) iOS ile aynı iş mantığını paylaşmanıza izin verir. Java'nın bu alanda karşılığı yok.
  • Sadece Java bilen junior developer: Önce temel OOP ve dil sentaksını Java'da pekiştirin, sonra Kotlin'e geçin. Geçiş aksini yapmaktan kolay.

Karar mantığını sadeleştirelim: yeni kod yazıyorsanız Kotlin, eski kod okuyorsanız Java. Hem yeni hem eski varsa ikisini de bilmek lazım — Kotlin %90 zaman, Java %10. Android dünyasının önümüzdeki yıllarda yönü bu. Sıralı bir müfredatla ilerlemek isterseniz Android Kotlin eğitimi dilin Android odaklı kullanımını adım adım ele alır.

Android programlama bir dil seçimi sorusu gibi görünür; aslında bir paradigma seçimi sorusudur. Java size klasik nesne yönelimli düşünmeyi öğretir, Kotlin onu üzerine ekleyip fonksiyonel araçları, null güvenliğini ve modern eşzamanlılığı dile yedirir. İkisi de aynı JVM üstünde çalışır, aynı projede birlikte yaşar, aynı kütüphaneleri çağırır — ama yazarken hissettirdikleri farkındadır. Yeni Android uygulamasının başlangıç noktası artık Kotlin; Java ise hâlâ önemli bir tarihsel ve pratik bağ.