Bölüm 4: Örnek Sorular

Java ile Nesne Yönelimli Programlama
Değerle aktarımstatic ve tanımlayıcılarYapıcı zinciri: this(...)a++ ve değerlendirme sırası Kapsam ve gölgelemeTür uyumuİşlem önceliğicontinue switch ve case etiketleriif içinde atamado-while
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Önce derleyici gibi bakmak

Bir kodun derlenip derlenmediğine karar vermek: tür uyumsuzluğu, yinelenen case etiketi, geçersiz tanımlayıcı.

Sonra JVM gibi çalıştırmak

Programı satır satır izleyip değişken, çağrı çerçevesi ve nesne tablosu tutarak çıktıyı kesin tahmin etmek.

Metot ve nesneler

Değerle aktarımı (pass-by-value), static üyeleri, gölgelemeyi ve this(...) ile yapıcı zincirini açıklamak.

İfade ve kontrol yapıları

a++, işlem önceliği, continue, switch düşmesi (fall-through), if içinde atama ve do-while tuzaklarını tanımak.

Giriş

“Çıktısı Nedir?” Sorusu Nasıl Çözülür?

1. Derlenir mi?

Her bildirimde türü kontrol edin (char d = "d"?), adları kontrol edin, case değerlerini hesaplayın. Tek bir hata varsa program hiç çalışmaz; cevap “derleme hatası” olur.

2. Nereden başlar?

Çalışma her zaman main’in ilk satırından başlar. Bir metot çağrısında yeni bir çağrı çerçevesi (stack frame) açılır, metot bitince kapanır.

3. Tabloyu tutun

Kâğıda değişkenlerin değerini, açık çerçeveleri ve new ile oluşan nesneleri yazın. Her atamada tabloyu güncelleyin; tahmin etmeyin, hesaplayın.

4. Çıktıyı harfiyen yazın

print satır sonu eklemez, println ekler. Boşluklar, iki nokta ve büyük/küçük harf de çıktının parçasıdır: "Renk:" ile "Renk: " farklıdır.

Bu bölümdeki 11 sorunun her biri önce soru olarak gelir (şıklı); bir sonraki slayt ise cevabı adım adım izleme ya da açıklama ile verir. Önce kendiniz çözün!

Değerle Aktarım

Soru 1

public class Ornek1 {
  public static void sayiyaEkle(int x, int miktar) {
    x = x + miktar;
  }
  public static void main(String[] args) {
    int a = 15;
    int b = 10;
    Ornek1.sayiyaEkle(a, b);
    System.out.println(a);
  }
}
Program ekrana ne yazar?
  1. 25
  2. 15
  3. 10
  4. Derleme hatası

İpucu: Java’da bir metoda değişkenin kendisi değil, değeri gönderilir.

Cevap

B) 15. sayiyaEkle, a’nın kopyası olan x’i değiştirir; a aynı kalır.

Değerle Aktarım · Adım adım

Soru 1: Değer Kopyalanır

Yığın (stack)main()a15b?

main başlar; çerçevesinde a = 15 oluşur.

Yığın (stack)main()a15b10

b = 10. Henüz hiçbir metot çağrılmadı.

Yığın (stack)sayiyaEkle()x15miktar10main()a15b10

Çağrıda değerler kopyalanır: x = 15, miktar = 10. x ile a ayrı kutulardır.

Yığın (stack)sayiyaEkle()x25miktar10main()a15b10

x = 15 + 10 = 25. Yalnızca kopya değişti; main’deki a hâlâ 15.

Yığın (stack)main()a15b10

Metot biter, çerçevesi silinir; x = 25 de onunla kaybolur. Metot void, bir şey döndürmez.

Yığın (stack)main()a15b10

println(a) → 15. Cevap: B.

public class Ornek1 {
  public static void sayiyaEkle(int x, int miktar) {
    x = x + miktar;
  }
  public static void main(String[] args) {
    int a = 15;
    int b = 10;
    Ornek1.sayiyaEkle(a, b);
    System.out.println(a);
  }
}

Değerle Aktarım

Değişikliği Kalıcı Yapmak: return

public class Ornek1b {
  public static int sayiyaEkle(int x, int miktar) {
    x = x + miktar;
    return x;
  }
  public static void main(String[] args) {
    int a = 15;
    int b = 10;
    a = Ornek1b.sayiyaEkle(a, b);
    System.out.println(a);
  }
}
Çıktı
25
Referanslar da kopyalanır. Parametre bir nesne referansıysa referansın kopyası gider: nesnenin alanları değiştirilebilir, ama parametreye yeni nesne atamak çağıranı etkilemez (Örnek Problem 2).
Değerle aktarım (pass-by-value)

Java her zaman değerle aktarır: parametre, argümanın kopyasıdır. Metodun içinde parametreye yapılan atama çağırana yansımaz.

Çözüm

Yeni değeri return ile döndürün ve çağıran tarafta atayın: a = sayiyaEkle(a, b);

Tanımlayıcılar ve Varsayılanlar

Soru 2

public class Ornek2 {
  private static int $;
  public static void main(String[] args) {
    String deger_1 = "1";
    System.out.print($);
    System.out.print(deger_1);
  }
}
Program derlenir mi? Derlenirse ne yazar?
  1. Derleme hatası: $ geçerli bir ad değil
  2. 01
  3. null1
  4. 1

İpucu: Alanlar (field) otomatik başlangıç değeri alır; yerel değişkenler almaz.

Cevap

B) 01. $ geçerli bir ad; static int alan varsayılan olarak 0’dır. İki print yan yana yazar.

Tanımlayıcılar ve Varsayılanlar

Soru 2: Geçerli Ad ve Varsayılan Değer

Tanımlayıcı (identifier) kuralları

Harf, rakam, _ ve $ içerebilir; rakamla başlayamaz, anahtar kelime olamaz, boşluk ve - içeremez. Tek başına _ da ad olarak kullanılamaz.

AdGeçerli mi?
$, deger_1, _x✓
1deger (rakamla başlıyor)✗
int, class (anahtar kelime)✗
my-var, ilk ad✗

$ geçerlidir ama derleyicinin ürettiği adlar için ayrılmış sayılır; kendi kodunuzda kullanmayın.

Alan türüVarsayılan değer
int, long, byte, short0
double, float0.0
booleanfalse
char'\u0000'
referans (String …)null
print($) → 0, ardından print(deger_1) → 1. print satır atlamadığı için çıktı 01 olur.

Yerel değişkenin varsayılan değeri yoktur: int i; System.out.println(i); → error: variable i might not have been initialized

Yapıcı Metotlar

Soru 3

public class Ornek3 {
  private String renk;
  public Ornek3() {
    this("beyaz");
  }
  public Ornek3(String renk) {
    this.renk = renk;
  }
  public static void main(String[] args) {
    Ornek3 e = new Ornek3();
    System.out.println("Renk:" + e.renk);
    Ornek3 ee = new Ornek3("kırmızı");
    System.out.println("Renk:" + ee.renk);
  }
}
Program ekrana ne yazar?
  1. Renk:null / Renk:kırmızı
  2. Renk:beyaz / Renk:kırmızı
  3. Derleme hatası: aynı adlı iki yapıcı
  4. Renk:beyaz / Renk:beyaz

İpucu: this(...), aynı sınıfın başka bir yapıcısını çağırır.

Cevap

B) Renk:beyaz, Renk:kırmızı. Parametresiz yapıcı this("beyaz") ile diğer yapıcıyı çağırır.

Yapıcı Metotlar · Adım adım

Soru 3: this(...) ile Yapıcı Zinciri

Yığın (stack)Öbek (heap)Ornek3()thismain()e?ee?Ornek3 #1renknull

new öbekte (heap) bir nesne ayırır; renk önce varsayılan null olur. Parametresiz yapıcı çalışmaya başlar.

Yığın (stack)Öbek (heap)Ornek3(String)thisrenk"beyaz"Ornek3()thismain()e?ee?Ornek3 #1renknull

this("beyaz") aynı nesne için Ornek3(String) yapıcısını çağırır: yeni bir çerçeve açılır.

Yığın (stack)Öbek (heap)Ornek3(String)thisrenk"beyaz"Ornek3()thismain()e?ee?Ornek3 #1renk"beyaz"

this.renk nesnenin alanı, sağdaki renk parametredir. Alan "beyaz" olur.

Yığın (stack)Öbek (heap)main()eee?Ornek3 #1renk"beyaz"

İki yapıcı da biter, çerçeveleri kapanır. e artık nesneyi gösteren referansı tutar.

Yığın (stack)Öbek (heap)main()eee?Ornek3 #1renk"beyaz"

"Renk:" + e.renk → Renk:beyaz. İki noktadan sonra boşluk yok.

Yığın (stack)Öbek (heap)Ornek3(String)thisrenk"kırmızı"main()eee?Ornek3 #1renk"beyaz"Ornek3 #2renknull

İkinci nesne: bu kez doğrudan Ornek3(String) çağrılır; parametre "kırmızı".

Yığın (stack)Öbek (heap)Ornek3(String)thisrenk"kırmızı"main()eee?Ornek3 #1renk"beyaz"Ornek3 #2renk"kırmızı"

this şimdi ikinci nesneyi gösterir; onun alanı "kırmızı" olur. Birinci nesne etkilenmez.

Yığın (stack)Öbek (heap)main()eeeOrnek3 #1renk"beyaz"Ornek3 #2renk"kırmızı"

ee ikinci nesneyi gösterir → Renk:kırmızı. Cevap: B.

public class Ornek3 {
  private String renk;
  public Ornek3() {
    this("beyaz");
  }
  public Ornek3(String renk) {
    this.renk = renk;
  }
  public static void main(String[] args) {
    Ornek3 e = new Ornek3();
    System.out.println("Renk:" + e.renk);
    Ornek3 ee = new Ornek3("kırmızı");
    System.out.println("Renk:" + ee.renk);
  }
}

Yapıcı Metotlar

Yapıcı Zinciri Kuralları

Aşırı yükleme (overloading)

Aynı adlı iki yapıcı, parametre listeleri farklı olduğu için geçerlidir: Ornek3() ve Ornek3(String).

this(...) ilk satırda

Başka bir yapıcıyı çağıran this(...), yapıcının ilk deyimi olmalıdır. Böylece varsayılan değerler tek bir yerde toplanır.

this.renk ↔ renk

Parametre, aynı adlı alanı gölgeler. Alana ulaşmak için this. gerekir; renk = renk; parametreyi kendine atar, alan null kalır.

public class Ornek3Hata {
  private String renk;
  public Ornek3Hata() {
    System.out.println("varsayılan");
    this("beyaz");
  }
  public Ornek3Hata(String renk) {
    this.renk = renk;
  }
}
Derleyici
Ornek3Hata.java:5: error: call to this must be first statement in constructor
    this("beyaz");
        ^
1 error

Artırma İşleci

Soru 4

public class Ornek4 {
  public static void main(String args[]) {
    int a = 0;
    while (a == a++) {
      a++;
      System.out.println(a);
    }
  }
}
Program ekrana ne yazar?
  1. 1
  2. 2
  3. Hiçbir şey yazmaz
  4. 2, 4, 6, … durmadan

İpucu: a++ önce eski değeri verir, sonra a’yı artırır. ==’in sol tarafı önce değerlendirilir.

Cevap

D) 2, 4, 6, … durmadan. a == a++ her zaman true’dur: döngü sonsuzdur.

Artırma İşleci · Adım adım

Soru 4: a == a++ Hep Doğru

a0koşul: a == a++–sol–a++–sonuç

a = 0.

a1koşul: a == a++0sol==0a++→truesonuç

Soldan sağa: sol a → 0; a++ → 0 verir, sonra a = 1. 0 == 0 → true.

a2koşul: a == a++–sol–a++–sonuç

Gövdedeki a++: a = 2.

a2koşul: a == a++–sol–a++–sonuç

println(a) → 2.

a3koşul: a == a++2sol==2a++→truesonuç

Yine iki taraf aynı değeri görür: 2 == 2 → true, ardından a = 3.

a4koşul: a == a++–sol–a++–sonuç

a = 4.

a4koşul: a == a++–sol–a++–sonuç

println(a) → 4.

a5koşul: a == a++4sol==4a++→truesonuç

Koşul her turda true: program 2, 4, 6, … yazarak sonsuza dek sürer (int taşsa bile).

public class Ornek4 {
  public static void main(String args[]) {
    int a = 0;
    while (a == a++) {
      a++;
      System.out.println(a);
    }
  }
}

Kapsam ve Gölgeleme

Soru 5

public class Ornek5 {
  private static int i = 1;
  public static void main(String argv[]) {
    System.out.println(i);
    int i = 2;
    Ornek5 ornek = new Ornek5();
    System.out.println(i);
    ornek.yazdir();
  }
  public static void yazdir() {
    System.out.println(i);
  }
}
Program ekrana ne yazar? (Her sayı ayrı satırda.)
  1. 1 2 2
  2. 1 2 1
  3. Derleme hatası: i iki kez tanımlı
  4. 2 2 1

İpucu: Yerel değişkenin kapsamı (scope) tanımlandığı satırdan başlar ve bloğun sonunda biter.

Cevap

B) 1, 2, 1. Yerel i yalnızca main’de, tanımlandığı satırdan sonra statik i’yi gölgeler.

Kapsam ve Gölgeleme · Adım adım

Soru 5: Hangi i?

Sınıf alanı (static)Ornek5i1Yığın (stack)Öbek (heap)main()ornek?

Bu satırda henüz yerel i yok; i sınıfın static alanıdır → 1.

Sınıf alanı (static)Ornek5i1Yığın (stack)Öbek (heap)main()i2ornek?

Yerel i = 2 tanımlanır. Alanla aynı ad yasaldır; bundan sonra main’de i yereli gösterir (gölgeleme).

Sınıf alanı (static)Ornek5i1Yığın (stack)Öbek (heap)main()i2ornekOrnek5 nesnesi

Bir nesne oluşturulur. Nesnede alan yok: static alan nesneye değil sınıfa aittir.

Sınıf alanı (static)Ornek5i1Yığın (stack)Öbek (heap)main()i2ornekOrnek5 nesnesi

Artık i yerel değişkendir → 2.

Sınıf alanı (static)Ornek5i1Yığın (stack)Öbek (heap)yazdir()main()i2ornekOrnek5 nesnesi

yazdir static’tir; nesne üzerinden çağrılsa da derleyici bunu Ornek5.yazdir() olarak çalıştırır.

Sınıf alanı (static)Ornek5i1Yığın (stack)Öbek (heap)yazdir()main()i2ornekOrnek5 nesnesi

yazdir çerçevesinde yerel i yok; main’in yereli görünmez → statik i → 1. Cevap: B.

public class Ornek5 {
  private static int i = 1;
  public static void main(String argv[]) {
    System.out.println(i);
    int i = 2;
    Ornek5 ornek = new Ornek5();
    System.out.println(i);
    ornek.yazdir();
  }
  public static void yazdir() {
    System.out.println(i);
  }
}

Veri Türleri

Soru 6

public class Ornek6 {
  public static void main(String[] args) {
    char d = "d";
    float f = 3.1415;
    int i = 34;
    byte b = 257;
    boolean isPresent = true;
  }
}
Hangi bildirimler derleme hatası verir?
  1. Yalnızca d
  2. d ve f
  3. d, f ve b
  4. Hiçbiri

İpucu: Tam sayı sabiti int, ondalıklı sabit double türündedir. byte: −128 … 127.

Cevap

C) d, f ve b. "d" bir String; 3.1415 bir double; 257 byte aralığının dışında.

Veri Türleri

Soru 6: Tür Uyumu

BildirimDerlenir?Neden / düzeltme
char d = "d";✗Çift tırnak String’dir. char için tek tırnak: 'd'
float f = 3.1415;✗Sabit double; daraltma kayıplı olabilir. 3.1415f yazın
int i = 34;✓int sabiti int’e
byte b = 257;✗257 > 127. (byte) 257 derlenir ama değer 1 olur
boolean isPresent = true;✓true/false geçerli
Derleyici
Ornek6.java:3: error: incompatible types: String cannot be converted to char
    char d = "d";
             ^
Ornek6.java:4: error: incompatible types: possible lossy conversion from double to float
    float f = 3.1415;
              ^
Ornek6.java:6: error: incompatible types: possible lossy conversion from int to byte
    byte b = 257;
             ^
3 errors
Düzeltilmiş hâlin çıktısı
d 3.1415 34 1 true

(byte) 257: 257 = 256 + 1 ve byte 256 değerde bir tur atar; geriye 1 kalır. Tür dönüştürme (cast) derleyiciyi susturur, taşmayı engellemez.

İşlem Önceliği

Soru 7

public class Ornek7 {
  public static void main(String[] args) {
    System.out.println(2 + 4 * 3 - 7);
    System.out.println((2 + 4) * (3 - 7));
    System.out.println(2 + (4 * 3) - 7);
    System.out.println(((2 + 4) * 3) - 7);
  }
}
Program ekrana ne yazar? (Her değer ayrı satırda.)
  1. 7, -24, 7, 11
  2. 11, -24, 7, 11
  3. 7, 24, 7, 11
  4. 11, -24, 7, 7

İpucu: Aynı öncelikteki işlemler soldan sağa yapılır.

Cevap

A) 7, -24, 7, 11. *, + ve -’den önce yapılır; parantez önceliği değiştirir.

İşlem Önceliği

Soru 7: İfadeleri Adım Adım İndirgemek

1) 2 + 4 * 3 - 7
2 + 4 * 3 - 7
2 + 12 - 7
14 - 7
= 7

* önce; sonra soldan sağa + ve -.

2) (2 + 4) * (3 - 7)
(2 + 4) * (3 - 7)
6 * (3 - 7)
6 * -4
= -24

Önce parantezler: 6 ve −4; çarpım negatif.

3) 2 + (4 * 3) - 7
2 + (4 * 3) - 7
2 + 12 - 7
14 - 7
= 7

Bu parantez zaten öncelikli olan işlemi sardığı için sonucu değiştirmez.

4) ((2 + 4) * 3) - 7
((2 + 4) * 3) - 7
(6 * 3) - 7
18 - 7
= 11

İç parantezden dışa: 6, 18, 11.

Öncelikİşleçler
1 (en yüksek)( )
2x++ x--
3++x --x tekli - !
4* / %
5+ -
6< <= > >=
7== !=
…&&, ||, = += -=
Çıktı
7
-24
7
11

İç İçe Döngüler

Soru 8

public class Ornek8 {
  public static void main(String[] args) {
    int i;
    int j;
    for (i = 1; i < 4; i++) {
      for (j = 2; j < 4; j++) {
        if (j == 3) {
          continue;
        }
        System.out.println("i: " + i + " j: " + j);
      }
    }
  }
}
Program ekrana ne yazar?
  1. 6 satır: her i için j: 2 ve j: 3
  2. 3 satır: j hep 2
  3. 3 satır: j hep 3
  4. Hiçbir şey: continue döngüden çıkar

İpucu: break döngüden çıkar; continue sıradaki tura geçer.

Cevap

B) 3 satır, j hep 2. continue yalnızca iç döngünün o turunu atlar.

İç İçe Döngüler · Adım adım

Soru 8: continue Turu Atlar

j = 2j = 3i = 1yazdıri = 2i = 3

Dış döngü i = 1, iç döngü j = 2 ile başlar. 2 == 3 yanlış → i: 1 j: 2 yazılır.

j = 2j = 3i = 1yazdırcontinuei = 2i = 3

j == 3 → true: continue yazdırmayı atlar, j++ ile iç döngünün koşuluna döner; j = 4, 4 < 4 yanlış → iç döngü biter.

j = 2j = 3i = 1yazdırcontinuei = 2yazdıri = 3

Dış döngü i = 2, iç döngü j = 2 ile başlar. 2 == 3 yanlış → i: 2 j: 2 yazılır.

j = 2j = 3i = 1yazdırcontinuei = 2yazdırcontinuei = 3

j == 3 → true: continue yazdırmayı atlar, j++ ile iç döngünün koşuluna döner.

j = 2j = 3i = 1yazdırcontinuei = 2yazdırcontinuei = 3yazdır

Dış döngü i = 3, iç döngü j = 2 ile başlar. 2 == 3 yanlış → i: 3 j: 2 yazılır.

j = 2j = 3i = 1yazdırcontinuei = 2yazdırcontinuei = 3yazdırcontinue

j == 3 → true: continue yazdırmayı atlar, j++ ile iç döngünün koşuluna döner.

j = 2j = 3i = 1yazdırcontinuei = 2yazdırcontinuei = 3yazdırcontinue

i = 4: 4 < 4 yanlış, program biter. 6 turdan 3’ü yazdı. Cevap: B.

public class Ornek8 {
  public static void main(String[] args) {
    int i;
    int j;
    for (i = 1; i < 4; i++) {
      for (j = 2; j < 4; j++) {
        if (j == 3) {
          continue;
        }
        System.out.println("i: " + i + " j: " + j);
      }
    }
  }
}

Çoklu Seçim

Soru 9

public class Ornek9 {
  public static void main(String args[]) {
    int num = 0;
    switch (num) {
      default:
        System.out.println("default");
      case 0:
        System.out.println("case1");
      case 10 * 2 - 20:
        System.out.println("case2");
        break;
    }
  }
}
Program derlenir mi? Derlenirse ne yazar?
  1. default, case1, case2
  2. case1, case2
  3. case1
  4. Derleme hatası

İpucu: case değeri bir sabit ifadedir; derleyici onu hesaplar.

Cevap

D) Derleme hatası. 10 * 2 - 20 derleme anında 0 olarak hesaplanır; case 0 iki kez yazılmış olur.

Çoklu Seçim

Soru 9: Yinelenen case Etiketi

Sabit ifade (constant expression)

case etiketine yalnızca derleme anında değeri bilinen ifadeler yazılır. Derleyici 10 * 2 - 20’yi 0 olarak hesaplar.

Her değer bir kez

Bir switch’te aynı değer iki etikette olamaz: case 0 ve case 10 * 2 - 20 çakışır. Program hiç çalışmaz.

default nerede olursa olsun

default en başta da yazılabilir; yalnızca hiçbir case eşleşmezse oraya atlanır.

Derleyici
Ornek9.java:9: error: duplicate case label
      case 10 * 2 - 20:
      ^
1 error
Etiketi case 10 * 2 - 10: (yani 10) yapınca program derlenir. Bir sonraki slayt, bu hâli üç farklı num değeriyle izler.

Çoklu Seçim · Adım adım

Düzeltilmiş Hâl: Etiketten Etikete Düşme

num = 0 → giriş: case 0:default:"default"case 0:"case1"case 10:"case2"; break

num = 0 → case 0 etiketine atlanır; default atlanır.

num = 0 → giriş: case 0:default:"default"case 0:"case1"case 10:"case2"; break

break yok: case1 yazıldıktan sonra case2’ye düşer; break ile çıkar.

num = 5 → giriş: default:default:"default"case 0:"case1"case 10:"case2"; break

num = 5 hiçbir case ile eşleşmez → default’a atlanır.

num = 5 → giriş: default:default:"default"case 0:"case1"case 10:"case2"; break

break olmadığı için alttaki etiketlere düşer (fall-through): üç satır yazılır, break durdurur. Etiketler yalnızca giriş noktasıdır.

public class Ornek9b {
  static void dene(int num) {
    System.out.println("num = " + num);
    switch (num) {
      default:
        System.out.println("default");
      case 0:
        System.out.println("case1");
      case 10 * 2 - 10:
        System.out.println("case2");
        break;
    }
  }
  public static void main(String args[]) {
    dene(0);
    dene(5);
  }
}

Atama ve Koşul

Soru 10

public class Ornek10 {
  public static void main(String args[]) {
    boolean myVal = false;
    if (myVal = true) {
      for (int i = 0; i < 2; i++) {
        System.out.println(i);
      }
    }
    else {
      System.out.println("else");
    }
  }
}
Program ekrana ne yazar?
  1. else
  2. 0, 1
  3. Derleme hatası
  4. 0, 1, 2

İpucu: = atama, == karşılaştırmadır. Atama ifadesinin de bir değeri vardır.

Cevap

B) 0, 1. myVal = true bir atamadır ve değeri true’dur; if dalı çalışır.

Atama ve Koşul · Adım adım

Soru 10: = mi, == mı?

myValfalsedeğişkenmyVal = true–koşulun değerii–döngü sayacı

myVal = false.

myValtruedeğişkenmyVal = truetruekoşulun değerii–döngü sayacı

Karşılaştırma değil, atama: myVal true olur ve ifadenin değeri de true’dur → if dalına girilir.

myValtruedeğişkenmyVal = truetruekoşulun değerii0döngü sayacı

i = 0, 0 < 2 → 0 yazılır.

myValtruedeğişkenmyVal = truetruekoşulun değerii1döngü sayacı

i = 1, 1 < 2 → 1 yazılır.

myValtruedeğişkenmyVal = truetruekoşulun değerii2döngü sayacı

i = 2: 2 < 2 yanlış, döngü biter. else dalı hiç çalışmaz. Cevap: B.

public class Ornek10 {
  public static void main(String args[]) {
    boolean myVal = false;
    if (myVal = true) {
      for (int i = 0; i < 2; i++) {
        System.out.println(i);
      }
    }
    else {
      System.out.println("else");
    }
  }
}

Atama ve Koşul

Atama Koşulu Ne Zaman Derlenir?

Yalnızca boolean ile

if koşulu boolean olmalıdır. boolean bir değişkene atama yapılırsa sonuç da boolean olduğundan kod sessizce derlenir ve hep aynı dala girer.

int ile derlenmez

C’den farklı olarak Java, sayıyı koşul olarak kabul etmez: if (sayi = 5) derleme hatasıdır.

Güvenli yazım

boolean değişkeni == true ile karşılaştırmayın, doğrudan yazın: if (myVal), if (!myVal). Böylece = yazım hatasına yer kalmaz.

public class Ornek10Int {
  public static void main(String args[]) {
    int sayi = 0;
    if (sayi = 5) {
      System.out.println("beş");
    }
  }
}
Derleyici
Ornek10Int.java:4: error: incompatible types: int cannot be converted to boolean
    if (sayi = 5) {
             ^
1 error

Döngü Koşulları

Soru 11

public class Ornek11 {
  public static void main(String[] args) {
    int i = 10;
    do {
      while (i < 15) {
        i = i + 20;
      }
    } while (i < 2);
    System.out.println(i);
  }
}
Program ekrana ne yazar?
  1. 10
  2. 30
  3. 50
  4. Sonsuz döngü

İpucu: do-while koşulu gövdeden sonra sınar: gövde en az bir kez çalışır.

Cevap

B) 30. do gövdesi bir kez çalışır: iç while i’yi 30 yapar; 30 < 2 yanlış olduğundan çıkılır.

Döngü Koşulları · Adım adım

Soru 11: do-while En Az Bir Kez

05101520253035i < 2i < 15i = 10i = 10

i = 10.

05101520253035i < 2i < 15i = 10iç while: 10 < 15 → doğru

do gövdesine koşulsuz girilir. İç while: 10 < 15 doğru.

05101520253035i < 2i < 15i = 30i = 10 + 20 = 30

i = 10 + 20 = 30.

05101520253035i < 2i < 15i = 30iç while: 30 < 15 → yanlış

30 < 15 yanlış: iç döngü biter (yalnızca bir tur döndü).

05101520253035i < 2i < 15i = 30do-while: 30 < 2 → yanlış

Şimdi do-while koşulu sınanır: 30 < 2 yanlış → dış döngüden çıkılır.

05101520253035i < 2i < 15i = 30çıktı: 30

println(i) → 30. Cevap: B.

public class Ornek11 {
  public static void main(String[] args) {
    int i = 10;
    do {
      while (i < 15) {
        i = i + 20;
      }
    } while (i < 2);
    System.out.println(i);
  }
}

Özet

Özet: 11 Soru, 11 Kavram

SoruKavramAnahtar fikirCevap
1Değerle aktarımMetot argümanın kopyasını değiştirir15
2Tanımlayıcı, varsayılan değer$ geçerli ad; static int → 001
3Yapıcı zincirithis("beyaz") diğer yapıcıyı çağırırRenk:beyaz, Renk:kırmızı
4a++a == a++ hep true2, 4, 6, … (sonsuz)
5Gölgeleme, staticYerel i yalnızca main’de görünür1, 2, 1
6Tür uyumu"d", 3.1415, 257 uyumsuzDerleme hatası (3)
7İşlem önceliği* önce, sonra soldan sağa7, −24, 7, 11
8continueYalnızca o turu atlar3 satır, j: 2
9case etiketi10 * 2 - 20 = 0 → yinelenen etiketDerleme hatası
10= / ==Atamanın değeri true0, 1
11do-whileGövde en az bir kez30

Özet

Sık Yapılan Hatalar (1): Derleme Hataları

Çift tırnakla char

char d = "d"; → error: incompatible types: String cannot be converted to char. Tek tırnak: 'd'.

f’siz float

float f = 3.1415; → error: incompatible types: possible lossy conversion from double to float.

Aynı değerde iki case

case 0 ve case 10 * 2 - 20 → error: duplicate case label.

this(...) ikinci satırda

Önce println, sonra this("beyaz") → error: call to this must be first statement in constructor.

Sayıyı koşul yapmak

if (sayi = 5) → error: incompatible types: int cannot be converted to boolean.

static bağlamdan örnek üyesi

main’den static olmayan yaz() çağrısı → error: non-static method yaz() cannot be referenced from a static context.

Özet

Sık Yapılan Hatalar (2): Derlenir ama Yanlış

Metot argümanı değiştirir sanmak

sayiyaEkle(a, b) sonrası a aynı kalır. Sonucu return ile döndürüp atayın.

if içinde =

boolean değişkenle if (myVal = true) derlenir ve her zaman doğru dala girer. if (myVal) yazın.

break unutmak

switch’te break yoksa eşleşen etiketten sonrakiler de çalışır (düşme). Her case’i break ile bitirin.

Alanı yerelle gölgelemek

Alanla aynı adlı yerel değişken, alanı gizler. Okunurluk için farklı ad seçin ya da Ornek5.i / this.renk yazın.

Bir ifadede ++ ile oynamak

a == a++, x++ + ++x gibi ifadeler doğru ama okunmazdır. Artırmayı ayrı satıra yazın.

continue ↔ break

continue sıradaki tura geçer, break döngüyü bitirir. İç içe döngülerde yalnızca en içteki döngüyü etkilerler.

Özet

Örnek Problemler (1): Diziler ve Nesneler Metotta

// 1
static void degistir(int[] dizi, int sayi) {
  dizi[0] = 99;
  sayi = 99;
}
// main içinde:
int[] d = new int[3];
int s = 1;
degistir(d, s);
System.out.println(d[0] + " " + s);
// 2
class Nokta { int x; }

static void tasi(Nokta p) {
  p.x = 5;
  p = new Nokta();
  p.x = 9;
}
// main içinde:
Nokta n = new Nokta();
n.x = 1;
tasi(n);
System.out.println(n.x);
Cevaplar
  1. 99 1. Dizi değişkeni bir referanstır; kopyası da aynı diziyi gösterir, dizi[0] = 99 asıl diziyi değiştirir. sayi ise s’nin kopyasıdır: s 1 kalır.
  2. 5. p.x = 5, n’nin gösterdiği nesneyi değiştirir. p = new Nokta() yalnızca kopya referansı yeni nesneye çevirir; p.x = 9 o yeni nesneye yazılır.

Özet

Örnek Problemler (2): static Sayaç ve İfadeler

// 3
class Sayac {
  static int toplam = 0;
  int adet = 0;
  Sayac() {
    toplam++;
    adet++;
  }
}
// main içinde:
Sayac s1 = new Sayac();
Sayac s2 = new Sayac();
Sayac s3 = new Sayac();
System.out.println(Sayac.toplam + " " + s3.adet);
// 4
int x = 5;
System.out.println(x++ + ++x);
System.out.println(x);
System.out.println(1 + 2 + "3" + 4 + 5);
Cevaplar
  1. 3 1. toplam static: üç nesne tek sayacı paylaşır → 3. adet her nesnede ayrıdır; s3.adet → 1.
  2. 12, 7, 3345. x++ 5 verir (x = 6), ++x önce artırır ve 7 verir: 5 + 7 = 12. 1 + 2 = 3 sayı toplamıdır; "3"’ten sonra her + birleştirmedir: "3345".

Özet

Alıştırmalar (1)

for (int i = 0; i < 5; i++) {
  if (i == 3) {
    break;
  }
  System.out.print(i);
}
System.out.println();
int g = 2;
switch (g) {
  case 1: System.out.print("A");
  case 2: System.out.print("B");
  case 3: System.out.print("C"); break;
  default: System.out.print("D");
}
System.out.println();
public class Alistirma2 {
  int sayi = 3;
  public static void main(String[] args) {
    System.out.println(sayi);
  }
}
  1. Üstteki kodun (bir main gövdesi) iki satırlık çıktısı nedir?
  2. Alttaki program derlenir mi? Derlenmezse hata nedir? İki farklı düzeltme önerin.
Cevaplar
  1. 012 ve BC. i == 3 olunca break döngüden çıkar. g = 2 → case 2’den girilir, B; case 3’e düşülür, C; break.
  2. Derlenmez: error: non-static variable sayi cannot be referenced from a static context. Alanı static int sayi = 3; yapın ya da new Alistirma2().sayi yazın.

Özet

Alıştırmalar (2)

class Kutu {
  Kutu() {
    this(1);
    System.out.print("A");
  }
  Kutu(int n) {
    System.out.print("B" + n);
  }
}
// main içinde:
new Kutu();
System.out.println();
char c = 'A';
c += 2;
System.out.println(c);
int i = 0;
do {
  i++;
} while (i < 0);
System.out.println(i);
  1. new Kutu() ne yazar? Yapıcıların çalışma sırasını çerçeve çerçeve çizin.
  2. c += 2 sonrası c nedir? c = c + 2; derlenir miydi?
  3. do-while koşulu baştan yanlışken i kaç olur? Aynı döngü while ile yazılsaydı?
Cevaplar
  1. B1A. Kutu() önce this(1) ile Kutu(int)’i çağırır (B1), o bitince kendi gövdesine döner (A).
  2. C ('A' + 2). c = c + 2; derlenmez: c + 2 bir int’tir → error: incompatible types: possible lossy conversion from int to char. += gizli bir tür dönüştürmesi içerir.
  3. 1: gövde koşuldan önce bir kez çalışır. while (i < 0) i++; ise hiç dönmez, i 0 kalır.

Özet

Kaynaklar

  • Oracle, The Java Tutorials: “Language Basics” (değişkenler, işleçler, kontrol akışı) ve “Classes and Objects” (yapıcılar, this, sınıf üyeleri).
  • Gosling ve diğ., The Java Language Specification, Java SE 21: §3.8 tanımlayıcılar, §4.12.5 varsayılan değerler, §6.4 gölgeleme, §8.8.7 yapıcı gövdesi, §14.11 switch, §15.7 değerlendirme sırası, §15.29 sabit ifadeler.
  • P. Deitel, H. Deitel, Java: How to Program, Pearson: işleç önceliği tablosu, kontrol deyimleri, metotlar.
  • K. Sierra, B. Bates, Head First Java, O’Reilly: değerle aktarım ve yığın/öbek çizimleri.
  • C. S. Horstmann, Core Java, Volume I: Fundamentals, Pearson: yapıcı zinciri ve static üyeler.
  • A. B. Downey, C. Mayfield, Think Java, O’Reilly (açık erişim): çıktı tahmini alıştırmaları.

Son

Bölüm 4: Örnek Sorular
Sonraki bölüm: Bölüm 5: Diziler
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.