Eğitim Portalı/Java/Type Casting (Tip Dönüşümü)
Java01-java/86-type-casting

Type Casting (Tip Dönüşümü)

Type casting, bir değeri/nesneyi bir tipten başka bir tipe dönüştürmektir. Java güçlü tipli bir dildir; bu dönüşümler kurallara bağlıdır. İki tamamen farklı bağlam vardır: ilkel tipler arasında (sayısal dönüşüm) ve ne…

Type Casting (Tip Dönüşümü)

Type casting, bir değeri/nesneyi bir tipten başka bir tipe dönüştürmektir. Java güçlü tipli bir dildir; bu dönüşümler kurallara bağlıdır. İki tamamen farklı bağlam vardır: ilkel tipler arasında (sayısal dönüşüm) ve nesne referansları arasında (kalıtım hiyerarşisinde). Her ikisinin de kendine özgü tuzakları vardır.

İlkel tip dönüşümleri

İlkel tiplerin bir "büyüklük sırası" vardır: byte → short → int → long → float → double (ve char → int).

Genişletme (widening) — otomatik

Küçük tipten büyük tipe dönüşüm otomatiktir ve güvenlidir (veri kaybı yok):

int i = 100;
long l = i;       // int -> long (otomatik)
double d = l;     // long -> double (otomatik)

Daraltma (narrowing) — açık cast, veri kaybı riski

Büyük tipten küçük tipe dönüşüm açık cast gerektirir ve veri kaybı/taşma olabilir:

double pi = 3.99;
int kesik = (int) pi;     // -> 3  (ondalık ATILIR, yuvarlanmaz!)
byte b = (byte) 300;      // -> taşar (byte aralığı -128..127)

Örnek 1 (./Ornek1.java) genişletme/daraltmayı, char ↔ int dönüşümünü ve önemli bir tuzağı gösterir:

int bölme tuzağı: 5 / 2 == 2 (ondalık atılır!). Ondalık sonuç için en az bir operand double olmalı: 5 / 2.0 == 2.5 veya (double) 5 / 2.

Nesne referansı dönüşümleri

Kalıtım hiyerarşisinde iki yön vardır:

Upcasting (alt → üst) — otomatik, güvenli

Hayvan h = new Kopek();   // Kopek bir Hayvandır -> otomatik

Her zaman güvenlidir. Polimorfizmin temelidir: üst tiple programlar, gerçek tip davranır (dinamik bağlama, topic 40).

Downcasting (üst → alt) — açık cast, ClassCastException riski

Hayvan h = new Kopek();
Kopek k = (Kopek) h;      // açık cast — nesne gerçekten Kopek'se güvenli

Ama nesne gerçekten o tip değilse çalışma zamanında ClassCastException atar. Bu yüzden:

if (h instanceof Kopek k) {   // pattern matching: kontrol + cast + bağlama (Java 16+)
    k.getir();
}

Örnek 2 (./Ornek2.java) upcasting, güvenli/yanlış downcasting ve pattern matching'i gösterir.

Derlenmeyen cast: Birbiriyle ilgisiz tipler arasında cast derlenmez (örn. String'i Integer'a cast edemezsin). Yalnızca aynı hiyerarşideki tipler arasında downcast denenebilir.

Autoboxing ile ilişki

İlkel ↔ wrapper dönüşümü (int ↔ Integer) ayrı bir mekanizmadır (autoboxing, topic 76); cast değildir, otomatik kutulama/kutu-açmadır ve kendi tuzakları vardır (null unboxing, ==).

Özet

İki tür tip dönüşümünü öğrendik: ilkel tipler arasında genişletme (otomatik) ve daraltma (açık cast + veri kaybı; int bölme tuzağı dahil — Örnek 1); nesne referansları arasında upcasting (güvenli) ve downcasting (ClassCastException riski, güvenli yol instanceof/pattern matching — Örnek 2). Tip dönüşümlerini doğru yapmak, hem doğruluk hem güvenlik için kritiktir. Sırada, karakterlerin altyapısı: Unicode ve karakter kodlama.

Kod Örnekleri(2)

Ornek1

çalıştırılabilir
Ornek1.java
1// Ornek1: İlkel tip dönüşümleri — genişletme (implicit) ve daraltma (explicit + veri kaybı).
2// Çalıştırma: java Ornek1.java
3public class Ornek1 {
4
5    public static void main(String[] args) {
6        // GENİŞLETME (widening): küçük tip -> büyük tip. OTOMATİK (veri kaybı yok).
7        int i = 100;
8        long l = i;          // int -> long (otomatik)
9        double d = l;        // long -> double (otomatik)
10        System.out.println("Genişletme: int " + i + " -> long " + l + " -> double " + d);
11
12        // DARALTMA (narrowing): büyük tip -> küçük tip. AÇIK cast gerekir; VERİ KAYBI olabilir!
13        double pi = 3.99;
14        int kesik = (int) pi;       // ondalık ATILIR (yuvarlama değil!) -> 3
15        System.out.println("\nDaraltma: (int) 3.99 = " + kesik + "  (ondalık atılır, yuvarlanmaz)");
16
17        long buyuk = 300;
18        byte b = (byte) buyuk;      // byte aralığı -128..127 -> taşar/sarmalanır
19        System.out.println("(byte) 300 = " + b + "  (byte aralığı taştı -> sarmalandı)");
20
21        // char <-> int: char aslında bir sayıdır (Unicode kodu).
22        char harf = 'A';
23        int kod = harf;             // char -> int otomatik (genişletme): 65
24        char sonraki = (char) (kod + 1); // int -> char için cast gerekir: 'B'
25        System.out.println("\n'A' -> int " + kod + ", (char)(65+1) -> '" + sonraki + "'");
26
27        // Aritmetikte otomatik genişletme: int / int = int (ondalık kaybolur!)
28        System.out.println("\n5 / 2 = " + (5 / 2) + "  (int bölme -> ondalık YOK)");
29        System.out.println("5 / 2.0 = " + (5 / 2.0) + "  (biri double -> sonuç double)");
30        System.out.println("(double) 5 / 2 = " + ((double) 5 / 2));
31
32        System.out.println("""
33
34                --- İlkel tip dönüşümleri ---
35                Genişletme (widening): byte->short->int->long->float->double. OTOMATİK, güvenli.
36                Daraltma (narrowing): ters yön. AÇIK cast '(tip)' gerekir; VERİ KAYBI/taşma olabilir.
37                  (int)3.99 -> 3 (ondalık atılır, YUVARLANMAZ); (byte)300 -> taşar.
38                char bir sayıdır (Unicode); char<->int dönüşümleri mümkün.
39                TUZAK: int/int bölme ondalığı atar; ondalık için en az bir operand double olmalı.""");
40    }
41}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// Ornek2: Referans (nesne) dönüşümleri — upcasting, downcasting, instanceof.
2// Çalıştırma: java Ornek2.java
3import java.util.List;
4
5public class Ornek2 {
6
7    static class Hayvan { String ses() { return "..."; } }
8    static class Kopek extends Hayvan { @Override String ses() { return "Hav"; } String getir() { return "topu getirdi"; } }
9    static class Kedi extends Hayvan { @Override String ses() { return "Miyav"; } }
10
11    public static void main(String[] args) {
12        // UPCASTING: alt tip -> üst tip. OTOMATİK ve her zaman güvenli.
13        Hayvan h = new Kopek();          // Kopek -> Hayvan (implicit)
14        System.out.println("Upcasting: " + h.ses() + " (gerçek tip Kopek -> dinamik bağlama)");
15
16        // DOWNCASTING: üst tip -> alt tip. AÇIK cast gerekir; YANLIŞSA ClassCastException.
17        if (h instanceof Kopek) {
18            Kopek k = (Kopek) h;         // güvenli (gerçekten Kopek)
19            System.out.println("Downcasting: " + k.getir());
20        }
21
22        // Yanlış downcast -> ClassCastException (çalışma zamanı hatası)
23        Hayvan kedi = new Kedi();
24        try {
25            Kopek yanlis = (Kopek) kedi; // Kedi, Kopek DEĞİL
26            System.out.println(yanlis);
27        } catch (ClassCastException e) {
28            System.out.println("\nYanlış downcast -> ClassCastException (Kedi, Kopek değil)");
29        }
30
31        // MODERN: pattern matching for instanceof (kontrol + cast tek adımda)
32        List<Hayvan> hayvanlar = List.of(new Kopek(), new Kedi(), new Kopek());
33        for (Hayvan a : hayvanlar) {
34            if (a instanceof Kopek kopek) {   // kontrol + güvenli cast + bağlama
35                System.out.println("Köpek özel: " + kopek.getir());
36            } else {
37                System.out.println("Diğer hayvan sesi: " + a.ses());
38            }
39        }
40
41        System.out.println("""
42
43                --- Referans (nesne) dönüşümleri ---
44                Upcasting (alt -> üst): otomatik, her zaman güvenli (Kopek bir Hayvandır).
45                Downcasting (üst -> alt): açık cast '(Tip)' gerekir; nesne gerçekten o tip DEĞİLSE ClassCastException.
46                GÜVENLİ yol: önce 'instanceof' ile kontrol et. EN İYİSİ: pattern matching 'if (x instanceof Tip t)'
47                  -> kontrol + cast + değişken bağlama tek adımda (Java 16+).
48                Not: birbiriyle ilgisiz tipler arasında cast DERLENMEZ (örn. String'i Integer'a cast edemezsin).""");
49    }
50}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.