Karar yapıları: if/else, mantıksal operatörler, switch
if, else if zinciri, iç içe if, &&, || ve ! ile kısa devre, switch ve fall-through. Vizede hem çıktı izleme hem de getSeason tipi metot yazma olarak gelir.
Program şimdiye kadar yukarıdan aşağı her satırı çalıştırdı. Karar yapıları (selection statements) bir koşula göre bazı satırları çalıştırıp bazılarını atlamayı sağlar. Vizede iki tip soru çıkar: koşulları takip edip neyin basıldığını bulmak ve “şu değere göre şunu döndür” diyen kısa metotlar yazmak (not harfi, ay adı, mevsim).
Altın kurallar:
- else if zincirinde ilk true olan dal çalışır, gerisine bakılmaz.
- Süslü parantez yoksa if tek bir ifadeyi kapsar. Girinti yanıltır.
&&ve||kısa devre yapar: sonuç belli olunca sağ taraf hiç çalışmaz.- switch’te break yoksa aşağı düşer (fall-through), default dahil.
=atama,==karşılaştırma. if içinde=derlenmez.
Karşılaştırma ve boolean ifadeler
Karşılaştırma operatörleri (relational operators) iki değeri karşılaştırır ve boolean (true/false) üretir.
| Operatör | Anlamı | a = 7, b = 3 iken |
|---|---|---|
== | eşit mi | a == b → false |
!= | eşit değil mi | a != b → true |
> < | büyük, küçük | a > b → true |
>= <= | büyük eşit, küçük eşit | a <= 7 → true |
int a = 7, b = 3;
System.out.println((a > b) + " " + (a == b) + " " + (a != b) + " " + (a <= 7));
boolean big = a > 5;
System.out.println(big);
true false true true
true
boolean bir değişkende saklanabilir ve doğrudan yazdırılabilir.
TUZAK · if içinde tek eşittir.
if (x = 5)derlenmez:incompatible types: int cannot be converted to boolean. if bir boolean ister,x = 5ise atamadır ve int üretir.
if ve if-else
int temp = 12;
if (temp > 25) {
System.out.println("Sicak");
} else {
System.out.println("Serin");
}
System.out.println("Bitti");
Serin
Bitti
Koşul true ise if bloğu, false ise else bloğu çalışır. İkisinden tam olarak biri çalışır. Bloktan sonraki satırlar (Bitti) her durumda çalışır.
else if zinciri
Birden çok aralık varsa else if kullanılır. Java koşulları yukarıdan aşağı dener, ilk true olanı çalıştırır, zincirin geri kalanını atlar.
public static String letter(int score) {
if (score >= 90) return "A";
else if (score >= 80) return "B";
else if (score >= 70) return "C";
else if (score >= 60) return "D";
else return "F";
}
letter(85), letter(90), letter(59) çağrıları:
B A F
85 için score >= 80 dalına gelindiğinde score < 90 olduğunu zaten biliyoruz; o yüzden score >= 80 && score < 90 yazmaya gerek yok.
TUZAK · yanlış sıra. Zinciri
if (score >= 60) return "D"; else if (score >= 70) ...diye küçükten başlatırsan 95 alan öğrenci de D alır, çünkü ilk true koşul>= 60. DoğrulamadaletterWrongOrder(95)gerçektenDdöndürdü. Alt sınırla çalışıyorsan büyükten küçüğe sırala.
Zincir ile ayrı if’ler farklıdır:
int s = 95;
if (s >= 90) System.out.print("A ");
if (s >= 80) System.out.print("B ");
if (s >= 70) System.out.print("C ");
A B C
Üç ayrı if, üçü de bağımsız kontrol edilir ve üçü de true.
Süslü parantez ve noktalı virgül tuzakları
int x = -2, cnt = 0, other = 0;
if (x > 0)
cnt++;
other++; // girinti yanıltıcı: bu satır if'in DIŞINDA
System.out.println(cnt + " " + other);
int y = -5;
if (y > 0); // sondaki ; boş bir ifade, if'in gövdesi bu
{
System.out.println("pozitif?");
}
0 1
pozitif?
İkinci örnekte if’in gövdesi o boş noktalı virgül. Alttaki süslü parantez bloğu if ile ilgisiz, her zaman çalışır. y negatif olduğu halde pozitif? basıldı.
Asılı else (dangling else)
int m = 5, n = 20;
if (m > 10)
if (n > 10)
System.out.println("ikisi de buyuk");
else
System.out.println("else kime ait?");
System.out.println("son");
son
else her zaman en yakın, eşleşmemiş if’e aittir: burada içteki if (n > 10). Girinti onu dıştaki if’e aitmiş gibi gösteriyor ama Java girintiye bakmaz. Dıştaki koşul false olduğu için içerideki hiçbir şey çalışmadı. Kaçınmanın yolu: her zaman { } kullan.
Mantıksal operatörler
| a | b | a && b (VE) | a || b (VEYA) | !a (DEĞİL) |
|---|---|---|---|---|
| true | true | true | true | false |
| true | false | false | true | false |
| false | true | false | true | true |
| false | false | false | false | true |
Öncelik: önce !, sonra &&, en son ||. Karşılaştırmalar bunlardan önce yapılır, o yüzden age >= 18 && student parantezsiz çalışır.
int age = 20;
boolean student = true;
System.out.println(age >= 18 && student);
System.out.println(age < 18 || !student);
System.out.println(!(age == 20));
System.out.println(true || false && false); // && önce: true || false
System.out.println((true || false) && false);
true
false
false
true
false
Kısa devre (short-circuit evaluation)
&&: sol taraf false ise sonuç zaten false, sağa bakılmaz.||: sol taraf true ise sonuç zaten true, sağa bakılmaz.
Bu bir koruma olarak kullanılır:
int d = 0;
if (d != 0 && 10 / d > 1) System.out.println("buyuk");
else System.out.println("guvenli");
guvenli
d != 0 false olduğu için 10 / d hiç hesaplanmadı, program çökmedi. Sırayı ters yazsaydın (10 / d > 1 && d != 0) ArithmeticException alırdın.
Sağ tarafta ++z gibi bir yan etki (side effect) varsa, kısa devre o yan etkinin hiç olmamasına neden olur. Vizede tam bu kurulur.
Koşul operatörü (ternary)
koşul ? değer1 : değer2 kısa bir if-else’tir; bir değer üretir.
int t1 = 8;
String parity = (t1 % 2 == 0) ? "even" : "odd";
System.out.println(parity);
even
switch
Bir değişkenin belirli değerlerine göre dallanmak için switch kullanılır. int, char, String (ve byte, short) ile çalışır; double ve boolean ile yazılmaz.
int day = 3;
switch (day) {
case 1: System.out.println("Mon"); break;
case 2: System.out.println("Tue"); break;
case 3: System.out.println("Wed"); break;
default: System.out.println("Other");
}
Wed
Kural: Java eşleşen case’e atlar, oradan aşağı doğru çalışmaya başlar ve break görene kadar devam eder. Hiçbir case eşleşmezse default çalışır (else gibi). default zorunlu değil.
Fall-through
int lvl = 2;
switch (lvl) {
case 1: System.out.println("one");
case 2: System.out.println("two");
case 3: System.out.println("three");
default: System.out.println("default");
}
two
three
default
case 2’den girildi, hiç break olmadığı için altındaki her şey, default da dahil çalıştı. case 1 yukarıda kaldığı için çalışmadı: switch eşleşen case’in üstüne asla çıkmaz.
Fall-through bilerek de kullanılır: birden çok değer aynı işi yapacaksa case’leri alt alta yazarsın.
char g = 'B';
switch (g) {
case 'A': case 'B': System.out.println("Iyi"); break;
case 'C': System.out.println("Orta"); break;
default: System.out.println("Zayif");
}
String cmd = "stop";
switch (cmd) {
case "go": System.out.println("Gidiyor"); break;
case "stop": System.out.println("Duruyor"); break;
default: System.out.println("?");
}
Iyi
Duruyor
Metot içinde switch: return ile
Metot bir değer döndürüyorsa her case’te return yazarsın. return metodu anında bitirdiği için break gerekmez. Yukarıdaki soru bankasındaki daysInMonth bu kalıbın örneği; mevsim, gün adı ve not harfi soruları da aynı iskeletle çözülür.
Sık yapılan hatalar
| Yanlış düşünce | Doğrusu |
|---|---|
if (x = 5) | if (x == 5); tek = derlenmez |
| else if’te true olan bütün dallar çalışır | Sadece ilk true dal |
| Girinti if’in kapsamını belirler | { } yoksa sadece bir ifade |
if (x > 0); zararsız | Boş gövde; alttaki blok her zaman çalışır |
| else dıştaki if’e aittir | En yakın eşleşmemiş if’e |
a || b && c soldan sağa | && önce: a || (b && c) |
Koşulun sağındaki ++z her zaman çalışır | Kısa devrede hiç çalışmaz |
| switch eşleşen case’i çalıştırıp çıkar | break yoksa aşağı düşer |
switch double ile çalışır | Çalışmaz; int, char, String kullan |
String’i == ile karşılaştır | equals; switch String’de bunu kendisi yapar |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
What is printed?
int x = 15;
if (x > 10) System.out.println("A");
else if (x > 5) System.out.println("B");
else System.out.println("C");Cevabı göster
else if zincirinde ilk true olan dal çalışır, gerisine bakılmaz. 15 > 10 true → A. 15 > 5 de true ama o dala hiç gelinmez.
What is printed?
int x = 15;
if (x > 10) System.out.print("A");
if (x > 5) System.out.print("B");
else System.out.print("C");
System.out.println();Cevabı göster
Bu sefer iki ayrı if var. Birinci if A basar. İkinci if bağımsız olarak kontrol edilir: 15 > 5 true → B. else sadece ikinci if'e aittir, çalışmaz.
What is printed?
int a = 4, b = 9;
System.out.println(a > 3 && b < 5);
System.out.println(a > 3 || b < 5);
System.out.println(!(a > 3) || b % 3 == 0);Cevabı göster
true
true
1) true && false → false. 2) true || false → true. 3) !(true) = false; 9 % 3 == 0 true; false || true → true.
What is printed?
int x = 0;
if (x > 0)
System.out.println("pos");
System.out.println("checked");Cevabı göster
Süslü parantez yoksa if sadece hemen altındaki tek ifadeyi kapsar. Girinti (indentation) Java için anlamsızdır. checked satırı if'in dışında, her zaman çalışır.
What is printed when day is (a) 2, (b) 4, (c) 7?
switch (day) {
case 1: System.out.println("Red");
case 2: System.out.println("Green");
case 3: System.out.println("Blue"); break;
case 4: System.out.println("Black");
default: System.out.println("White");
}Cevabı göster
(a) case 2'den gir, break yok → case 3'e düş (fall-through), Blue, break → çık. (b) case 4'ten gir, break yok → default'a düşer: Black, White. (c) eşleşen case yok → sadece default: White. Her kelime ayrı satırda basılır.
What is printed?
int q = 3, z = 0;
if (q > 5 && ++z > 0) System.out.println("in");
System.out.println(z);
if (q < 5 || ++z > 0) System.out.println("in2");
System.out.println(z);Cevabı göster
in2
0
Kısa devre (short-circuit): && solu false ise sağa hiç bakmaz, ++z çalışmaz → z = 0. || solu true ise sağa bakmaz, yine ++z çalışmaz → z hâlâ 0. Koşul true olduğu için in2 basılır.
What is printed?
int a = 2, b = 8;
if (a > 5)
if (b > 5)
System.out.println("X");
else
System.out.println("Y");
System.out.println("Z");Cevabı göster
Asılı else (dangling else): else, girintiye bakılmaksızın en yakın eşleşmemiş if'e, yani if (b > 5)'e aittir. Dış if (a > 5) false olduğu için içerideki her şey atlanır. Sadece Z basılır.
What is printed?
int n = 7;
String res = (n > 5) ? (n > 10 ? "big" : "medium") : "small";
System.out.println(res);Cevabı göster
Koşul operatörü (ternary) koşul ? a : b. 7 > 5 true → içteki ifadeye bak: 7 > 10 false → "medium".
What is printed?
String w = "B";
switch (w) {
case "A": System.out.print("1 ");
case "B": System.out.print("2 ");
case "C": System.out.print("3 "); break;
default: System.out.print("4 ");
}Cevabı göster
switch String ile de çalışır (equals ile karşılaştırır). "B" eşleşir → 2 , break yok → 3 , break. default'a gelinmez.
What is printed?
int score = 72;
if (score >= 90) System.out.println("A");
if (score >= 70) System.out.println("C");
else if (score >= 60) System.out.println("D");
else System.out.println("F");Cevabı göster
İlk if bağımsız ve false. İkinci if ayrı bir zincir başlatır: 72 >= 70 true → C, zincirin geri kalanı atlanır.
Write a static method daysInMonth(int month) that uses a switch to return 28 for February, 30 for April, June, September and November, 31 for the other months, and -1 for an invalid month.
Cevabı göster
Aynı sonucu veren case'leri alt alta yaz (bilinçli fall-through). return metodu bitirdiği için break gerekmez.public static int daysInMonth(int month) { switch (month) { case 2: return 28; case 4: case 6: case 9: case 11: return 30; case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; default: return -1; }}Test: daysInMonth(4) → 30, daysInMonth(7) → 31, daysInMonth(2) → 28, daysInMonth(13) → -1.
Write a static method isLeapYear(int year): a year is a leap year if it is divisible by 4 but not by 100, or if it is divisible by 400. Use a single return statement.
Cevabı göster
Kuralı kelimesi kelimesine mantıksal operatörlere çevir. && önceliği || 'den yüksek olsa da parantez yazmak okunurluğu artırır.public static boolean isLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;}Test: 2024 → true, 1900 → false (100'e bölünüyor, 400'e bölünmüyor), 2000 → true, 2026 → false.
Doğrulama: Tüm çıktılar JDK 26 ile çalıştırıldı (verify/SEN1001/W03.java). daysInMonth ve isLeapYear metotları birkaç girdiyle test edildi. if (x = 5) hatası verify/SEN1001/err/IfAssign.java javac ile derlenerek alındı.