if-else Karar Yapıları
Giriş — Program Nasıl Karar Verir?
Bir programı düşün. Satır satır yukarıdan aşağıya çalışıyor, her şey sırayla. Ama gerçek hayat böyle değil, değil mi? Sabah kalktığında "hava yağmurluysa şemsiye al, değilse alma" diye düşünürsün. İşte programlar da böyle karar vermeli.
Java'da karar vermenin en temel yolu if-else yapısıdır. Bu ders boyunca bu yapıyı sıfırdan öğrenecek, iç içe kullanımlarını görecek ve yaygın hatalara karşı hazırlıklı olacaksın.
Analoji: if-else yapısını bir yol kavşağı gibi düşün. Kavşağa geldiğinde bir tabelaya bakıyorsun — koşul doğruysa sola, yanlışsa sağa gidiyorsun. Program da her if ifadesinde böyle bir kavşağa gelir.
if Yapısı — En Basit Karar
if yapısı, bir koşul doğruysa (true) belirli bir kod bloğunu çalıştırır. Koşul yanlışsa (false) o blok tamamen atlanır.
Söz dizimi:
if (koşul) {
// koşul true ise çalışır
}Parantez içindeki koşul her zaman boolean bir ifade olmalı — yani sonucu true ya da false olan bir şey.
Örnek: Basit if
int sicaklik = 35;
if (sicaklik > 30) {
System.out.println("Hava çok sıcak, bol su iç!");
}
System.out.println("Program devam ediyor...");Bu örnekte sicaklik > 30 ifadesi true döner, bu yüzden "Hava çok sıcak" mesajı yazdırılır. Eğer sicaklik değişkeni 25 olsaydı, o satır atlanacaktı ama "Program devam ediyor" yine yazdırılacaktı.
Örnek: Koşul false ise
int yas = 15;
if (yas >= 18) {
System.out.println("Oy kullanabilirsiniz.");
}
System.out.println("Hoşça kalın.");Burada yas >= 18 ifadesi false olduğu için "Oy kullanabilirsiniz" asla yazdırılmaz. Sadece "Hoşça kalın" çıktısı görülür.
💡 İpucu:
ifbloğunun içinde tek bir satır varsa süslü parantez kullanmadan da yazabilirsin. Ama her zaman süslü parantez kullan. Okumayı kolaylaştırır ve ileride satır eklediğinde hata yapmanı önler.
// Çalışır ama tehlikeli
if (yas >= 18)
System.out.println("Oy kullanabilirsiniz.");
// Daha güvenli — her zaman bunu tercih et
if (yas >= 18) {
System.out.println("Oy kullanabilirsiniz.");
}if-else — İki Yoldan Biri
Bazen koşul doğru değilse de bir şey yapmak istersin. İşte else bunun için var.
if (koşul) {
// koşul true ise
} else {
// koşul false ise
}Örnek: Sınav Geçme Kontrolü
int puan = 42;
if (puan >= 50) {
System.out.println("Tebrikler, geçtiniz!");
} else {
System.out.println("Maalesef kaldınız.");
}puan 42 olduğu için koşul false döner ve else bloğu çalışır: "Maalesef kaldınız."
Örnek: Çift/Tek Sayı Kontrolü
int sayi = 17;
if (sayi % 2 == 0) {
System.out.println(sayi + " çift sayıdır.");
} else {
System.out.println(sayi + " tek sayıdır.");
}% (mod) operatörü bir sayının 2'ye bölümünden kalanı verir. 17 % 2 = 1, yani 0'a eşit değil — else bloğu çalışır.
else if — Çoklu Koşul Zincirleme
Hayatta ikiden fazla seçenek olabilir. Hava sadece sıcak veya soğuk değil — ılık da olabilir. else if ile birden fazla koşulu sırayla kontrol edebilirsin.
if (koşul1) {
// koşul1 true ise
} else if (koşul2) {
// koşul2 true ise
} else if (koşul3) {
// koşul3 true ise
} else {
// hiçbiri true değilse
}Önemli kural: Java yukarıdan aşağıya kontrol eder. İlk true olan koşulun bloğunu çalıştırır ve geri kalanları atlar. Yani sıralama önemlidir!
Örnek: Not Derecelendirme
int puan = 78;
if (puan >= 90) {
System.out.println("AA — Mükemmel!");
} else if (puan >= 80) {
System.out.println("BA — Çok iyi");
} else if (puan >= 70) {
System.out.println("BB — İyi");
} else if (puan >= 60) {
System.out.println("CB — Orta");
} else if (puan >= 50) {
System.out.println("CC — Geçer");
} else {
System.out.println("FF — Kaldı");
}puan 78. Java sırayla kontrol eder:
78 >= 90? Hayır.78 >= 80? Hayır.78 >= 70? Evet! → "BB — İyi" yazdırılır, geri kalanlar kontrol edilmez.
Örnek: Mevsim Belirleme
int ay = 7;
String mevsim;
if (ay == 12 || ay == 1 || ay == 2) {
mevsim = "Kış";
} else if (ay >= 3 && ay <= 5) {
mevsim = "İlkbahar";
} else if (ay >= 6 && ay <= 8) {
mevsim = "Yaz";
} else if (ay >= 9 && ay <= 11) {
mevsim = "Sonbahar";
} else {
mevsim = "Geçersiz ay!";
}
System.out.println(ay + ". ay → " + mevsim);Bu örnekte || (VEYA) ve && (VE) mantıksal operatörlerini kullandık. Birden fazla koşulu birleştirmek için bunlara ihtiyacın olacak.
⚠️ Dikkat:
else ifzincirinde koşulları dar olandan geniş olana sırala. Eğerpuan >= 50koşulunu en başa koyarsan, 90 puan alan öğrenci de "CC — Geçer" alır, çünkü ilk eşleşen koşul çalışır!
İç İçe if (Nested if)
Bazen bir koşulun içinde başka bir koşul kontrol etmen gerekir. Bu durumda if bloğunun içine başka bir if yazarsın.
Örnek: Yaş ve Ehliyet Kontrolü
int yas = 20;
boolean ehliyetVar = true;
if (yas >= 18) {
if (ehliyetVar) {
System.out.println("Araba kullanabilirsiniz.");
} else {
System.out.println("Yaşınız uygun ama ehliyetiniz yok.");
}
} else {
System.out.println("18 yaşından küçüksünüz.");
}Burada önce yaş kontrol ediliyor. Yaş 18 ve üzeriyse, iç if ile ehliyet kontrolü yapılıyor.
Örnek: Giriş Doğrulama
String kullaniciAdi = "admin";
String sifre = "1234";
if (kullaniciAdi.equals("admin")) {
if (sifre.equals("admin123")) {
System.out.println("Giriş başarılı!");
} else {
System.out.println("Şifre yanlış!");
}
} else {
System.out.println("Kullanıcı bulunamadı!");
}💡 İpucu: İç içe if yapılarını 2 seviyeden fazla kullanma. 3-4 seviye iç içe girince kod okunmaz hale gelir. Böyle durumlarda guard clause veya metotlara ayırma tekniklerini kullan (bunları B03 Best Practices dersinde göreceğiz).
Ne zaman iç içe if kullanmalı?
İç içe if, ikinci koşulun anlamlı olması için birinci koşulun doğru olması gerektiğinde mantıklıdır. Yani koşullar bağımlı olduğunda kullan. Bağımsız koşulları && ile birleştirebilirsin:
// İç içe if yerine — daha temiz
if (yas >= 18 && ehliyetVar) {
System.out.println("Araba kullanabilirsiniz.");
}Ternary (Koşul) Operatörü
Java'da if-else'in kısa yolu var: ternary operatörü. Üç parçadan oluştuğu için bu adı almış.
değişken = (koşul) ? değerTrue : değerFalse;Koşul true ise soru işaretinden sonraki değer, false ise iki noktadan sonraki değer atanır.
Örnek: Basit Ternary
int yas = 20;
String durum = (yas >= 18) ? "Yetişkin" : "Çocuk";
System.out.println(durum); // YetişkinBu, aşağıdaki if-else ile aynı şey:
String durum;
if (yas >= 18) {
durum = "Yetişkin";
} else {
durum = "Çocuk";
}Örnek: Mutlak Değer
int sayi = -7;
int mutlak = (sayi >= 0) ? sayi : -sayi;
System.out.println(mutlak); // 7Örnek: Maks Değer Bulma
int a = 15, b = 23;
int max = (a > b) ? a : b;
System.out.println("Büyük olan: " + max); // 23⚠️ Dikkat: Ternary operatörünü sadece basit değer atamaları için kullan. İç içe ternary yazmak kodu okunmaz hale getirir:
// KÖTÜ — bunu yapma!
String sonuc = (puan >= 90) ? "AA" : (puan >= 80) ? "BA" : (puan >= 70) ? "BB" : "Diğer";
// Bu durumda if-else if zinciri çok daha okunur.Koşullarda Kullanılan Operatörler
if koşullarında kullanabileceğin operatörleri hatırlayalım:
Karşılaştırma Operatörleri
| Operatör | Anlam | Örnek |
|---|---|---|
== | Eşit mi? | x == 5 |
!= | Eşit değil mi? | x != 0 |
> | Büyük mü? | x > 10 |
< | Küçük mü? | x < 100 |
>= | Büyük veya eşit mi? | x >= 18 |
<= | Küçük veya eşit mi? | x <= 50 |
Mantıksal Operatörler
| Operatör | Anlam | Örnek | ||||
|---|---|---|---|---|---|---|
&& | VE (her ikisi de true) | x > 0 && x < 100 | ||||
| `\ | \ | ` | VEYA (en az biri true) | `x < 0 \ | \ | x > 100` |
! | DEĞİL (tersini alır) | !ehliyetVar |
Short-circuit (Kısa Devre) Değerlendirme
&& ve || operatörleri kısa devre mantığıyla çalışır:
&&: Sol taraffalseise sağ tarafı kontrol etmez (zaten sonuçfalse).||: Sol taraftrueise sağ tarafı kontrol etmez (zaten sonuçtrue).
String isim = null;
// Güvenli kontrol — null ise sağ tarafı çalıştırmaz
if (isim != null && isim.length() > 0) {
System.out.println("İsim: " + isim);
}Eğer isim null ise, isim.length() çağrılsaydı NullPointerException alırdık. Ama && kısa devre yaptığı için sol taraf false olunca sağ tarafa bakmaz. Bu çok kullanışlı bir tekniktir.
String Karşılaştırma — == vs equals()
Bu, yeni başlayanların en çok hata yaptığı konulardan biri. Dikkatli oku.
String s1 = "Merhaba";
String s2 = "Merhaba";
String s3 = new String("Merhaba");
System.out.println(s1 == s2); // true (String pool)
System.out.println(s1 == s3); // false (farklı referans!)
System.out.println(s1.equals(s3)); // true (içerik aynı)Kural: String'leri karşılaştırırken her zaman `.equals()` kullan. == operatörü referansları (bellek adreslerini) karşılaştırır, içeriği değil.
String sifre = kullanicidanAl();
// YANLIŞ
if (sifre == "admin123") { ... }
// DOĞRU
if (sifre.equals("admin123")) { ... }
// DAHA GÜVENLİ — NullPointerException'dan korunur
if ("admin123".equals(sifre)) { ... }Son satırdaki "sabit değeri sola koyma" tekniğine dikkat et. Eğer sifre null ise, sifre.equals(...) patlar ama "admin123".equals(null) sadece false döner.
Yaygın Hatalar ve Tuzaklar
1. Atama vs Karşılaştırma
int x = 5;
// YANLIŞ — atama yapıyor, karşılaştırma değil!
// Java'da bu derleme hatası verir (boolean bekleniyor)
if (x = 10) { ... }
// DOĞRU
if (x == 10) { ... }Java'da if içi boolean olmak zorunda olduğu için x = 10 derleme hatası verir. Ama boolean değişkenlerde bu tuzağa düşebilirsin:
boolean aktif = false;
// YANLIŞ — aktif'e true atıyor, her zaman çalışır!
if (aktif = true) { ... }
// DOĞRU
if (aktif == true) { ... }
// EN DOĞRU — zaten boolean, karşılaştırmaya gerek yok
if (aktif) { ... }2. Boş if Bloğu (Yanlışlıkla Noktalı Virgül)
int x = 5;
// HATALI — if'ten sonra ; koydun, blok bağımsız çalışır!
if (x > 10);
{
System.out.println("Bu her zaman çalışır!");
}if satırının sonundaki ; if'i bitirir. Süslü parantez içindeki kod koşuldan bağımsız çalışır. Bu çok sinsi bir hatadır.
3. Süslü Parantez Unutmak
if (puan >= 50)
System.out.println("Geçtiniz");
System.out.println("Tebrikler"); // Bu HER ZAMAN çalışır!Süslü parantez olmadan sadece ilk satır if'e bağlıdır. İkinci satır her durumda çalışır. Bu yüzden her zaman süslü parantez kullan.
4. Floating-point Karşılaştırma
double a = 0.1 + 0.2;
// YANLIŞ — floating-point hassasiyet sorunu!
if (a == 0.3) {
System.out.println("Eşit");
}
// Bu blok çalışmaz! Çünkü 0.1 + 0.2 = 0.30000000000000004
// DOĞRU — epsilon ile karşılaştır
if (Math.abs(a - 0.3) < 0.0001) {
System.out.println("Yaklaşık eşit");
}Ondalık sayıları == ile karşılaştırma! Bu sadece Java'ya özgü değil, tüm programlama dillerinde olan bir durum.
5. Dangling else Problemi
int x = 5, y = 10;
// Bu else hangi if'e ait?
if (x > 0)
if (y > 0)
System.out.println("İkisi de pozitif");
else
System.out.println("Bu ne zaman çalışır?");else her zaman en yakın if'e aittir. Yani bu else, içteki if (y > 0)'a bağlıdır, dıştakine değil. Süslü parantez kullanarak bunu netleştir:
if (x > 0) {
if (y > 0) {
System.out.println("İkisi de pozitif");
} else {
System.out.println("x pozitif ama y değil");
}
}Pratik Örnekler
Örnek 1: Artık Yıl Kontrolü
Bir yılın artık yıl olması için:
4'e bölünebilmeli VE 100'e bölünememeli
VEYA 400'e bölünebilmeli
int yil = 2024;
if ((yil % 4 == 0 && yil % 100 != 0) || yil % 400 == 0) {
System.out.println(yil + " artık yıldır.");
} else {
System.out.println(yil + " artık yıl değildir.");
}Örnek 2: Üçgen Geçerlilik Kontrolü
Üç kenarın üçgen oluşturması için, herhangi iki kenarın toplamı üçüncü kenardan büyük olmalı.
int a = 3, b = 4, c = 5;
if (a + b > c && a + c > b && b + c > a) {
System.out.println("Bu kenarlar bir üçgen oluşturur.");
if (a == b && b == c) {
System.out.println("Eşkenar üçgen");
} else if (a == b || b == c || a == c) {
System.out.println("İkizkenar üçgen");
} else {
System.out.println("Çeşitkenar üçgen");
}
} else {
System.out.println("Bu kenarlar üçgen oluşturmaz!");
}Örnek 3: BMI (Vücut Kitle İndeksi) Hesaplama
double kilo = 75.0;
double boy = 1.78;
double bmi = kilo / (boy * boy);
System.out.printf("BMI: %.1f → ", bmi);
if (bmi < 18.5) {
System.out.println("Zayıf");
} else if (bmi < 25.0) {
System.out.println("Normal");
} else if (bmi < 30.0) {
System.out.println("Kilolu");
} else {
System.out.println("Obez");
}boolean Değişkenlerle if Kullanımı
boolean değişkenler zaten true veya false olduğu için, karşılaştırma operatörüne gerek yok:
boolean ogrenciMi = true;
boolean bursluMu = false;
// GEREKSIZ — == true yazmana gerek yok
if (ogrenciMi == true) { ... }
// TEMİZ
if (ogrenciMi) { ... }
// GEREKSIZ
if (bursluMu == false) { ... }
// TEMİZ
if (!bursluMu) { ... }Boolean değişken isimlerini soru formunda yaz: isActive, hasPermission, canDrive. Bu, if koşullarını İngilizce bir cümle gibi okumanı sağlar:
if (hasPermission && isActive) {
// "İzni var VE aktif ise"
}if-else vs Ternary — Hangisini Kullanalım?
| Durum | Tercih |
|---|---|
| Basit değer atama | Ternary |
| Birden fazla satır çalıştırma | if-else |
| 3+ koşul | if-else if |
| Yan etki (side effect) olan işlem | if-else |
// Ternary uygun
int max = (a > b) ? a : b;
String mesaj = (puan >= 50) ? "Geçti" : "Kaldı";
// if-else uygun — birden fazla işlem var
if (puan >= 50) {
System.out.println("Geçtiniz");
gecenSayisi++;
listeye.ekle(ogrenci);
} else {
System.out.println("Kaldınız");
kalanSayisi++;
}if ile null Kontrolü
Java'da NullPointerException en sık karşılaşılan hatalardan biridir. Bir nesne null ise, onun metodunu çağırmak programı patlatır. Bu yüzden null kontrolü yapmak kritik önem taşır.
String isim = null;
// PATLAR — NullPointerException!
// System.out.println(isim.length());
// Güvenli yol
if (isim != null) {
System.out.println("İsim uzunluğu: " + isim.length());
} else {
System.out.println("İsim belirlenmemiş.");
}Null kontrolü genellikle metodun en başında yapılır. Bu "guard clause" tekniğinin temelidir (Best Practices dersinde detaylandıracağız):
public void selamla(String isim) {
if (isim == null) {
System.out.println("Merhaba, misafir!");
return;
}
System.out.println("Merhaba, " + isim + "!");
}Koşullu Atama Desenleri
Pratikte if-else'in en yaygın kullanımlarından biri koşullu atamadır. Bir değişkene koşula göre değer vermek istiyorsun.
Desen 1: Önce Varsayılan, Sonra Değiştir
String indirimMesaji = "İndirim yok";
if (toplamTutar > 500) {
indirimMesaji = "%20 indirim kazandınız!";
} else if (toplamTutar > 200) {
indirimMesaji = "%10 indirim kazandınız!";
}
System.out.println(indirimMesaji);Bu desende değişkene önce varsayılan bir değer atanır, sonra koşullar onu değiştirebilir. Eğer hiçbir koşul tutmazsa varsayılan kalır.
Desen 2: Her Dalda Atama
double vergiOrani;
if (gelir <= 32000) {
vergiOrani = 0.15;
} else if (gelir <= 70000) {
vergiOrani = 0.20;
} else if (gelir <= 170000) {
vergiOrani = 0.27;
} else if (gelir <= 880000) {
vergiOrani = 0.35;
} else {
vergiOrani = 0.40;
}
double vergi = gelir * vergiOrani;Bu desende her dalda atama yapılır. Dikkat: son else olmazsa ve hiçbir koşul tutmazsa, değişken atanmamış kalır ve Java derleme hatası verir. Java, "belki atanmadı" diye şikayet eder.
Gerçek Dünya Senaryosu: Kullanıcı Girişi Doğrulama
Bir kullanıcı kayıt formu düşün. Birden fazla alanı kontrol etmen gerekiyor:
String email = "user@example.com";
String sifre = "abc123";
int yas = 16;
boolean gecerli = true;
if (email == null || email.isEmpty()) {
System.out.println("Hata: E-posta boş olamaz!");
gecerli = false;
}
if (sifre == null || sifre.length() < 6) {
System.out.println("Hata: Şifre en az 6 karakter olmalı!");
gecerli = false;
}
if (yas < 18) {
System.out.println("Hata: 18 yaşından küçükler kayıt olamaz!");
gecerli = false;
}
if (gecerli) {
System.out.println("Kayıt başarılı!");
} else {
System.out.println("Lütfen hataları düzeltip tekrar deneyin.");
}Burada dikkat et: else if değil, bağımsız if'ler kullandık. Çünkü tüm hataları göstermek istiyoruz, sadece ilkini değil. Eğer else if kullansaydık, ilk hatadan sonra diğerlerini kontrol etmezdi.
💡 İpucu: Bağımsız koşulların hepsini kontrol etmek istiyorsan ayrı
if'ler, sadece ilk eşleşeni istiyorsanelse ifzinciri kullan.
if-else ve Enum Kullanımı
Enum değerlerini kontrol etmek de if-else'in yaygın kullanımlarından biridir. Ancak enum'larla genellikle switch daha uygun olur (bir sonraki dersimiz). Yine de basit durumlarda if-else güzel çalışır:
enum Rol { ADMIN, EDITOR, VIEWER }
Rol kullaniciRolu = Rol.EDITOR;
if (kullaniciRolu == Rol.ADMIN) {
System.out.println("Tam yetki — her şeyi yapabilirsiniz.");
} else if (kullaniciRolu == Rol.EDITOR) {
System.out.println("Düzenleme yetkisi — içerik yazabilirsiniz.");
} else if (kullaniciRolu == Rol.VIEWER) {
System.out.println("Sadece görüntüleme yetkisi.");
} else {
System.out.println("Tanımsız rol!");
}Enum'larda == kullanabilirsin çünkü enum değerleri tekil (singleton) nesnelerdir. equals() da çalışır ama == daha yaygın ve null-safe'tir (null enum'da equals çağırırsan patlar, == patlamaz).
Performans Notu
if-else zincirlerinde Java koşulları sırayla kontrol eder. 10 koşullu bir zincirde en kötü durumda 10 karşılaştırma yapılır. Bu çoğu durumda sorun olmaz ama en olası koşulu en başa koymak iyi bir alışkanlıktır:
// Eğer kullanıcıların %80'i VIEWER ise, bunu başa koy
if (rol == Rol.VIEWER) {
// En sık karşılaşılan durum
} else if (rol == Rol.EDITOR) {
// Daha az sık
} else if (rol == Rol.ADMIN) {
// En nadir
}Bu tür mikro-optimizasyonlar büyük projelerde fark yaratabilir. Ama önce okunabilirlik, sonra performans!
Özet
`if` tek başına kullanılır — koşul doğruysa çalışır, değilse atlanır.
`if-else` iki yoldan birini seçer — koşul true ise if bloğu, false ise else bloğu.
`else if` zincirleme koşullar için — ilk eşleşen çalışır, geri kalanlar atlanır.
Ternary operatörü (
? :) basit atamalar için if-else'in kısa hali — karmaşık durumlarda kullanma.String karşılaştırmasında `==` yerine `.equals()` kullan —
==referansları,.equals()içeriği karşılaştırır.Her zaman süslü parantez kullan — tek satırlık bloklarda bile. Dangling else ve ekleme hatalarını önler.
AI Asistan
Sorularını yanıtlamaya hazır