+ Yüklə

Transkript

+ Yüklə
Java programming and practices
Bilgisayar Mühendisi
Okan Bilke
JAVA DİLİYLE
PROGRAMLAMA
Part I
© Okan Bilke
Web Adresi: www.elektroarge.com
Email: [email protected]
Location: Türkiye
Ders 1 - Java Diline Giriş ................................................................................ 9
Ders 2 - JDK Kurulumu ....................................................................... 15
Ders 3 - Eclipse Kurulumu ................................................................... 18
Ders 4 - Eclipse Ortamını Tanıyalım ..................................................... 19
Ders 5 - Java İle İlk Programımız ......................................................... 32
Ders 6 - Eclipse Üzerinde Debug İşlemleri ............................................. 40
Ders 7 - Paket (Package) Kavramı ........................................................ 45
Ders 8 - Değişkenler ve Veri Tiplerine Giriş........................................... 50
Ders 9 - Değişken Tanımlama Kuralları ................................................ 51
Ders 10 - Primitif Tipler ....................................................................... 53
Ders 11 - Referans Tipler...................................................................... 56
Ders 12 - Boxing ve Unboxing Kavramı ................................................ 62
Ders 13 - Lokal Değişkenler .................................................................. 62
Ders 14 - Sabit Tanımlama ................................................................... 65
Ders 15 - Tip Dönüşümleri.................................................................... 66
Ders 16 - Java'da Kullanılan Anahtar Kelimeler ................................... 71
Ders 17 - Operatörlere Giriş ................................................................. 71
Ders 18 - Atama Operatörleri ............................................................... 71
Ders 19 - İlişkisel Operatörler ............................................................... 76
Ders 20 - Aritmetik Operatörler ........................................................... 78
Ders 21 - Mantıksal Operatörler ........................................................... 83
Ders 22 - Bitsel Operatörler .................................................................. 86
Ders 23 - Tip Karşılaştırma Operatörü ................................................. 90
Ders 24 - Operatör Önceliği .................................................................. 90
Ders 25 - Kontrol Yapıları .................................................................... 92
Ders 26 - Döngüler ............................................................................. 102
Ders 27 - Break ve Continue İfadeleri.................................................. 114
Ders 28 - Metod Nedir? ...................................................................... 116
Ders 29 - Metod Oluşturma ................................................................ 117
Ders 30 - Parametresiz Metodlar ........................................................ 117
Ders 31 - Parametreli Metodlar .......................................................... 121
Ders 32 - Metodlara Dizi Türünden Parametre Geçirmek ................... 127
Ders 33 - Metodları Aşırı Yükleme (Overloading)................................ 131
Ders 34 - Metodlarda Özyineleme (Recursion) .................................... 134
Ders 35 - Static Metodlar .................................................................... 138
Ders 36 - Dizilere Giriş ....................................................................... 142
Ders 37 - Bir Dizinin Boyutu ............................................................... 149
Ders 38 - Dizileri Kopyalama .............................................................. 151
Ders 39 - Dizileri Sıralama.................................................................. 155
Ders 40 - Dizilerde Arama .................................................................. 156
Ders 41 - Dizileri Karşılaştırma........................................................... 158
Ders 42 - Çok Boyutlu Diziler ............................................................. 159
Ders 43 - String[] Args Dizisi............................................................... 166
Ders 44 - Arrays Sınıfı Metodları ........................................................ 171
Ders 45 - Scanner Sınıfına Giriş .......................................................... 176
Ders 46 - JOptionPane Kullanımı ....................................................... 186
Ders 47 - Nesneye Yönelik Programlamaya Giriş ................................ 196
Ders 48 - Sınıf ve Nesne Kavramları.................................................... 196
Ders 49 - Sınıf ve Nesne Değişkenleri ................................................... 203
Ders 50 - Pass By Value - Pass By Reference........................................ 207
Ders 51 - Yapıcılar (Constructor)........................................................ 211
Ders 52 - Kapsülleme (Encapsulation)................................................. 217
Ders 53 - This Anahtar Kelimesi ......................................................... 232
Ders 54 - Static Anahtar Kelimesi ....................................................... 235
Ders 55 - Enum Kavramı.................................................................... 239
Ders 56 - Annotation Kavramı ............................................................ 248
Ders 57 - Garbage Collector (Çöp Toplayıcı) ....................................... 252
Ders 58 - Kalıtım Kavramına Giriş ..................................................... 256
Ders 59 - Super Class ve Sub Class Kavramları ................................... 258
Ders 60 - Super Metodu ile Üst Sınıfın Yapıcısını Çağırmak ................ 263
Ders 61 - Metod Overriding................................................................ 268
Ders 62 - Final Anahtar Kelimesi ........................................................ 278
Ders 63 - Upcasting ve Downcasting Kavramları ................................. 284
Ders 64 - Soyut Sınıflar ve Metodlara Giriş ......................................... 291
Ders 65 - Soyut Sınıf ve Kalıtm Arasındaki İlişki ................................. 292
Ders 66 - Soyut Sınıf Örneği................................................................ 293
Ders 67 - Arayüz Kavramına Giriş ..................................................... 299
Ders 68 - Arayüz Örneği..................................................................... 301
Ders 69 - Arayüzlerde Genişletilme Özelliği......................................... 305
Ders 70 - Arayüz İçerisinde Başka Bir Arayüz Kulanma ..................... 308
Ders 71 - Dahili Sınıflara Giriş ............................................................ 310
Ders 72 - Dahili Üye Sınıflar ............................................................... 311
Ders 73 - Dahili Üye Sınıflar ve Erişim Belirteçleri............................... 313
Ders 74 - Yerel Sınıflar ....................................................................... 321
Ders 75 - İsimsiz Sınıflar ..................................................................... 323
Ders 76 - Çok Biçimlilik (Polimorfizm) Kavramına Giriş..................... 324
Ders 77 - Geç Bağlama ....................................................................... 330
Ders 78 - Instanceof İle Tip Kontrolü .................................................. 333
Ders 79 - Math Sınıfına Giriş .............................................................. 339
Ders 80 - Math.pow Metodu İle Sayının Üssünü Alma ......................... 339
Ders 81 - Math.sqrt Metodu İle Sayının Karekökünü Alma ................. 341
Ders 82 - Math.abs Metodu İle Sayının Mutlak Değerini Alma ............ 341
Ders 83 - Math.floor Metodu İle Sayıyı Alt Değere Yuvarlama ............ 342
Ders 84 - Math.ceil Metodu İle Sayıyı Üst Değere Yuvarlama .............. 344
Ders 85 - Math.max Metodu İle Büyük Sayıyı Bulma .......................... 344
Ders 86 - Math.min Metodu İle Küçük Sayıyı Bulma........................... 345
Ders 87 - Math.random Metodu İle Rastgele Sayı Üretme ................... 346
Ders 88 - Math.toDegrees Metodu İle Radyanı Dereceye Çevirme........ 354
Ders 89 - Math.toRadians Metodu İle Dereceyi Radyana Çevirme ....... 355
Ders 90 - Math.sin Metodu İle Sinüs Bulma ........................................ 356
Ders 91 - Math.asin Metodu İle Ters Sinüs Bulma ............................... 357
Ders 92 - Math.cos Metodu İle Cosinüs Bulma .................................... 357
Ders 93 - Math.acos İle Ters Cosinüs Bulma........................................ 358
Ders 94 - Math.PI İle Pi Sabitini Kullanma ......................................... 359
Ders 95 - Logaritma Metodları ........................................................... 360
Ders 96 - String Sınıfına Giriş ............................................................. 362
Ders 97 - String Nesnesinin Uzunluğu ................................................. 363
Ders 98 - Karakter Katarlarını Birleştirmek ....................................... 364
Ders 99 - String Nesnelerini Karşılaştırma .......................................... 366
Ders 100 - Karakter Metodları............................................................ 374
Ders 101 - String Düzenleme Metodları............................................... 380
Ders 102 - StringTokenizer ve StringBuffer Sınıfları............................ 385
Ders 103 - Exceptions (İstisnalar) ........................................................ 398
Ders 104 - Hata Yakalama (Try - Catch Blokları)................................ 398
Ders 105 - Finally Bloğu...................................................................... 407
Ders 106 - Finally Bloğunda Try - Catch Kullanımı ............................. 408
Ders 107 - Birden Fazla Hata Yakalama ............................................. 410
Ders 108 - Throw Anahtar Kelimesi.................................................... 412
Ders 109 - Throws Anahtar Kelimesi .................................................. 413
Ders 110 - Exception Türü Oluşturma ................................................ 419
Ders 111 - Hata Türleri ...................................................................... 422
Ders 112 - I/O Kavramına Giriş .......................................................... 424
Ders 113 - File Sınıfının Kullanımı ...................................................... 427
Ders 114 - FileReader İle Dosya Oluşturma ......................................... 434
Ders 115 - FileWriter İle Dosyaya Yazma............................................ 437
Ders 116 - FileInputStream İle Dosya Okuma ..................................... 441
Ders 117 - FileOutputStream İle Dosyaya Yazma ................................ 443
Ders 118 - BufferedReader İle Dosyadan Okuma ................................ 444
Ders 119 - BufferedWriter İle Dosyaya Yazma .................................... 447
Ders 120 - BufferedInputStream İle Dosya Okuma.............................. 448
Ders 121 - BufferedOutputStream ile Dosyaya Yazma......................... 450
Ders 122 - Scanner Sınıfı İle Dosya Okuma ......................................... 451
Ders 123 - Scanner Sınıfı Yapıcıları..................................................... 456
Ders 124 - Rastgele Erişimli Dosyalarda Okuma ve Yazma.................. 457
Ders 125 - Object Serialization (Nesne Serileştirme)............................. 462
Ders 126 - Koleksiyonlara Giriş .......................................................... 472
Ders 127 - Collection Arayüzü ............................................................ 473
Ders 128 - Iterator .............................................................................. 476
Ders 129 - Set (Kümeler) .................................................................... 477
Ders 130 - Liste Yapıları (List) ............................................................ 485
Ders 131 - LinkedList (Bağlı Liste)...................................................... 490
Ders 132 - Map Arayüzü .................................................................... 498
Ders 133 - Olay Yönetimine Giriş........................................................ 507
Ders 134 - Olay Sınıfları ..................................................................... 508
Ders 135 - Olay Dinleyicileri (Event Listeners)..................................... 521
Ders 136 - Fare ve Klavye Olay Metodlarının Kullanımı...................... 526
Ders 137 - GUI (Graphical User Interface) Nedir?............................... 530
Ders 138 - GUI Kurulumu .................................................................. 531
Ders 139 - GUI Projesi Oluşturma ...................................................... 533
Ders 140 - Swing ................................................................................ 538
Ders 141 - JFrame .............................................................................. 539
Ders 142 - Container .......................................................................... 542
Ders 143 - JLabel ............................................................................... 544
Ders 144 - JButton.............................................................................. 548
Ders 145 - JTextField ......................................................................... 552
Ders 146 - JComboBox....................................................................... 554
Ders 147 - JRadioButton .................................................................... 557
Ders 148 - JCheckBox ........................................................................ 560
Ders 149 - JToggleButton ................................................................... 563
Ders 150 - JTable ............................................................................... 565
Ders 151 - JList .................................................................................. 568
Ders 152 - JScrollPane........................................................................ 572
Ders 153 - JTabbedPane..................................................................... 574
Ders 154 - JTree ................................................................................. 577
Ders 155 - Layout (Yerleşim Düzenleri)............................................... 581
Ders 156 - Veritabanı Kavramına Giriş............................................... 587
Ders 157 - Veritabanı Yönetim Sistemleri (VTYS) ............................... 589
Ders 158 - JDBC Tanımı .................................................................... 589
Ders 159 - Temel SQL Komutları ....................................................... 591
Ders 160 - MySQL Kurulumu ............................................................ 594
Ders 161 - MySQL İçin JDBC Connector............................................ 596
Ders 162 - JDBC Bileşenleri................................................................ 599
Ders 163 - JDBC İle Veri Sorgulama................................................... 608
Ders 164 - JDBC İle Veritabanına Veri Ekleme ................................... 610
Ders 165 - JDBC İle Veritabanından Veri Silme .................................. 612
Ders 166 - JDBC İle Veritabanındaki Verileri Güncelleme .................. 614
Ders 167 - Navicat Kurulumu ............................................................. 615
Ders 168 - Navicat İle Örnek Uygulama .............................................. 617
Ders 169 - Thread Kavramına Giriş.................................................... 631
Ders 170 - Thread Oluşturma ............................................................. 631
Ders 171 - Thread'i Başlatmak ve Durdurmak .................................... 636
Ders 172 - Thread'i Beklemeye Almak ve Devam Ettirmek.................. 639
Ders 173 - Bir Thread Nesnesine Öncelik Atamak ............................... 641
Ders 174 - Thread'in Çalışıp Çalışmadığının Kontrolü ........................ 644
Ders 175 - MultiThreading ................................................................. 646
Ders 176 - Switch İçerisinde String İfadeleri Kıyaslama ....................... 649
Ders 177 - Sayılarda Altçizgi Kullanarak Sayıları Bölümleme .............. 651
Ders 178 - İkili Tabandaki Sayıları Değişkenlerde Tutma .................... 652
Ders 179 - Hata Yakalamada Yeni Catch Bloğu Sistemi ...................... 654
Ders 180 - Hata Yakalamada Finally Bloğunun Alternatifi .................. 656
Ders 181 - Elmas Operatör İçerisindeki Tanım Zorunluluğu ............... 658
Ders 182 - Safevarags İle Uyarı ve Hata Giderimi ................................ 658
Ders 1 - Java Diline Giriş
JAVA DİLİNİN KISA TARİHİ
Java, Sun Microsystems firmasının mühendislerinden James
Gosling tarafından geliştirilmiş olup, yine Sun Microsystems tarafından 23
Mayıs 1995 yılında piyasaya sürülen, açık kaynak kodlu nesneye yönelik bir
programlama dilidir. Java 1.0 ile başlayan serüven, günümüzde Java SE 7.0'a
kadar gelmiştir. Kısıtlı özelliklere sahip olan Java 1.0 sürümünde büyük
değişiklikler yaparak Java 1.2 çıkarılmıştır ve buna Platform 2 adı verilmiştir.
Bu şekilde hızlı ilerlemeler kaydederek Java 7.0'a kadar gelinmiştir.
Sun Microsystems, daha sonra Oracle tarafından satın alınmıştır.
Java, platformdan bağımsız çalışma gereksinimi sonucunda ortaya çıkmıştır.
Eskiden bir program, yazıldığı işletim sisteminin dışında başka bir işletim
sistemi üzerinde çalışmıyordu. İleride göreceğimiz JVM sayesinde, artık Java
ile yazılmış programlar, her işletim sistemi üzerinde çalışabilecek hale
gelmiştir.
Java dili, çoğu özelliğini C ve C++ dillerinden almıştır. Nesneye yönelik
programlama kısmında C++'a yakındır. Syntax(söz dizimi) olarak ise C diline
benzer. C dilini bilenler, Java'nın nesneye yönelik programlama kısmına kadar
olan yerleri anlamakta zorluk çekmeyeceklerdir.
Java'nın simgesi bilindiği üzere bir kahve fincanıdır. Bu dil ilk geliştirilmeye
başlandığında adı Oak olarak belirlenmişti. Fakat bu isimde başka bir dil
olduğu fark edilince, o anda bir kahvehanede bulunan Java geliştiricileri grubu,
buradaki kahve markasından esinlenerek Java ismini vermişlerdir.
JAVA DİLİNİN ÜSTÜNLÜKLERİ
Java dilinin en önemli özelliği platformdan bağımsız çalışması, yüksek
performanslı, güvenilir ve esnek bir dil olmasıdır.
Java, temel olarak güvenliği ön planda tutar. Bu konuyu en önde tutan ilk
dildir. Bunun yanında daha birçok özelliği ile Java, masaüstü bilgisayarlardan
mobil aygıtlara, akıllı kartlardan oyun konsollarına, yazıcılardan tıbbi cihazlara
kadar birçok yerde kullanılmaktadır.
Java dili ile profesyonel yazılımlar geliştirildiği zaman bunun karşılığını tam
olarak verir ve size yeteneklerini gösterir. Kurumsal uygulamalarda çok
kullanılması, bunun en önemli göstergesidir.
Diğer dillerin aksine Java dili, derlendikten sonra çıktı olarak byte
code oluşturur. Daha sonra JVMsayesinde bu kodlar, yorumlanarak çalışır hale
getirilir. Bu özellik Java'nın hem taşınabilir hem de platformdan bağımsız bir
dil olmasını sağlamıştır. Bu özelliğe bir kere çalıştır her yerde kullan özelliği
denir ve bu şekilde tanınır. Aynı zamanda Java, hem derlenen hem
de yorumlanan bir dildir.
Java dili ile ayrıca web uyumlu uygulamalar geliştirilebilir. JSP(Java Server
Page), Servlet gibi web tabanlı uygulamalarda da kullanılır. JSP, sunucu
tarafında çalışan dinamik web uygulamaları geliştirmeye yarayan bir
dildir. Servlet ise yazılmış JSP sayfasının Java koduna dönüştürülmüş şeklidir.
Java'nın çıkış tarihi ile internetin kendini göstermeye başlaması aynı döneme
denk geldiği için Java, ağ sistemleri ile iç içedir.
C++ diline yakın olmasına rağmen C++ dilinden basittir. Bu dilden farklı olarak
otomatik bellek tahsisi yapar ve işi biten nesneler bellekten silinir.
Kullanılmayan nesneler Garbage Collector ile toplanarak bellekte gereksiz
kullanım yapılmaz. C++ dilinde bellek kaçakları meydana gelir ve yapısı
Java'daki gibi değildir. Ayrıca C++ dili ile yazdığımız programı, Java'da daha
az kod satırı ile yazabiliriz.
Java'nın önemli bir üstünlüğü de multithreading'e elverişli olmasıdır. Birden
fazla işin aynı anda yapılması anlamına gelen bu özellik, Java'nın temel
yapısında vardır.
Güvenliğin önemsendiği Java dilinde, API'ler sayesinde şifreleme, sayısal imza
gibi güvenlik önlemleri alınabilir. Ağ ortamındaki güvenlik derecesi oldukça
yüksektir.
C dilinde kullanılan pointer kavramının yerini Java'da referans almıştır. Nesne
ve değişkenlerin adresi pointer ile tutuluyorken; Java'da bu karmaşıklık
kaldırılarak referans kavramı getirilmiştir.
Java, çok zengin bir kütüphaneye sahiptir ve bunlar ücretsiz olarak temin
edilebilir. Xml, ağ, arayüz gibi konularda uygulama geliştirmek için bize
yardımcı olabilecek kütüphaneler mevcuttur. Buna Java API
Kütüphanesi denir.
Programlama ile ilgilenen bazı arkadaşların dilinde şöyle bir söz vardır:
"Facebook bile Php ile yazılmış. O yüzden Php bayağı gelişmiş bir dil ve çok
kullanılıyor" diye. Aslında Facebook'un arka planında birçok Java uygulaması
çalışır.
Java, framework konusunda oldukça gelişmiştir. İhtiyaca göre gerekli
framework'lar bulunmaktadır. Bir web uygulaması, oyun, otomasyon gibi
projeler için farklı framework'lar kullanılır.
Java, dediğimiz gibi platformdan bağımsız çalışır. Nedir bu kavram? Java'da
bunu hangi yapı sağlar? Şimdi Java ile ilgili temel kavramları görelim. Bunlar;
Java ile program geliştirmeye başlamadan önce bilmemiz gereken temel
kavramlardır.
JVM(JAVA VIRTUAL MACHINE - JAVA SANAL MAKİNESİ)
Java programları derlendikten sonra bilgisayarın anlayacağı dile dönüştürülür.
Buna byte kod denir. Byte kod ile java programlarının platformdan bağımsız
çalışması sağlanır. Byte kod bir kere oluşturulur ve her işletim sisteminde
çalışır. Buna write once run everywhere de denir. Bunu sağlayan
yapı JVM(Java Virtual Machine)'dir. Java programlarının çalışma mantığını
daha detaylı bir şekilde anlatalım. Java programları nesne ve sınıflardan oluşur.
Yazılmış olan sınıfların bulunduğu dosyaların uzantısı .java'dır.
Bu .java uzantılı dosyalar, bir derleyici yardımıyla derlenir ve byte kod adı
verilen makina kodlarına dönüştürülür. Artık bu dosyaların
uzantısı .class olmuştur. Bu işlem yalnızca bir kez yapılır. Bu .class uzantılı
byte kodlar, JVM yardımıyla her işletim sisteminde çalışır hale gelmiştir. JVM,
bu byte kodları adım adım yorumlar. Yazılan java programlarının diğer işletim
sistemlerinde de çalışabilmesi için o makinede JVM kurulu olması gerekir.
Hazır olan byte kodları, o makine üzerinde yorumlayarak işletim sisteminin
kullanımına sunar. Böylece byte kodları, üzerinde çalıştığı sisteme uygun hale
getirir. Günümüzde neredeyse her platform için yazılmış JVM'ler
bulunmaktadır.
Istisnalar:
!
JVM, Java'daki bir kere yaz her yerde çalıştır kavramında başrol
oynayarak, Java dilini bir adım öne çıkarmıştır.
JVM, sadece java dilinde yazılmış programları değil, byte kod'a
dönüştürülebilen her dili çalıştırılabilir.
Yukarıdaki şekilde JVM'nin işletim sistemi için önemi gösterilmiştir.
Derlenerek Byte kod'a çevrilen kaynak kodlar, JVM sayesinde her işletim
sistemi üzerinde çalışabilir.
JRE(JAVA RUNTIME ENVIRONMENT - JAVA ÇALIŞMA ORTAMI)
Java ile yazılmış olan programları çalıştırmak için JRE kurulu olmalıdır. Bir
uygulama geliştirdiğimiz zaman bunu kendi bilgisayarımızda çalıştırmamız için
gereklidir. Bunu C# dilinde kod yazdığımızda, bunları çalıştırabilmek için .Net
framework'a ihtiyaç duymamıza benzetebiliriz.
Java kodları, derlendikten sonra doğrudan bir makine üzerinde çalışamadığı
için byte kodlara dönüştürülmesi gerekir. Bunu yapan mekanizma JRE'dir.
Dönüştürülen byte kodları ise JVM yorumlar. JRE'nin içerisinde java
kütüphaneleri ve JVM sanal makinesi bulunur. JRE yüklediğimiz zaman
otomatik olarak JVM de yüklemiş oluruz.
JVM kavramını açıklarken, java kodlarının bilgisayarımızda çalışabilmesi için
JVM kurulu olmalıdır demiştik. JRE içerisinde JVM bulunduğu için, Java
kodlarını çalıştırmak için yalnızca JRE yüklemek yeterlidir.
Istisnalar:
JDK kullanarak geliştirdiğimiz bir uygulamayı çalıştırmak için
gereken JRE sürümü, o uygulamayı geliştirmek için kullanılan JDK
sürümünden daha yüksek olmalıdır. JDK 1.4 ile geliştirilen bir
uygulama, JRE 1.3 ile çalışmaz, daha yüksek bir sürüm gerekir.
JDK(JAVA DEVELOPMENT KIT - JAVA GELİŞTİRME KİTİ)
Java'nın inceliklerini ve performansını gördükten sonra bir Java uygulaması
geliştirmek isteyebiliriz. Bunun için ihtiyaç duyacağımız tek şey JDK'dır. JDK,
Java uygulamaları geliştirmek için bize bütün araçları sunar. İçerisinde Java
kütüphaneleri, Java Compiler ve Interpreter, JVM ve JRE içerir. Görüldüğü gibi
JDK'lar, JVM ve JRE'yi barındırır. Uygulama geliştirmek istiyorsanız, yalnızca
JDK yüklemeniz yeterlidir. Çünkü JDK içerisinde JRE bulunur. JRE içerisinde
de JVM bulunur.
Istisnalar:
!
JDK, uygulama geliştirmeye JRE, uygulama çalıştırmaya yarar. JVM
ise platformdan bağımsız bir ortam sağlayarak, derlenen kodların
başka platformlarda da çalışmasını sağlar.
Java'da ilk JDK sürümü 1.0 ile başlamıştır. Bu sürümde birçok eksiklikleri
bulunmaktaydı. Eksiklikler giderilerek sürekli gelişen JDK sürümleri
günümüzde JDK 7.0'a kadar gelmiştir. Bu evrede, ileride
göreceğimizScanner sınıfları, gelişmiş for döngüleri ve daha bunun gibi birçok
yapı eklenmiş ve geliştiricilere sunulmuştur.
J2EE, J2SE, J2ME KAVRAMLARI
Java'da birçok farklı alanda uygulama geliştirmek mümkündür. Uygulamalar
kullanıldığı alanlara göre farklı platformlara bölünmüştür.
J2EE (ENTERPRISE EDITION): Kurumsal uygulamalar, web servisleri gibi
gelişmiş uygulamalar geliştirmek için kullanılır. Gelişmiş uygulamalar
geliştirildiği için n katmanlı mimariler kullanılır. Bünyesinde Servlet, JPA,
JSP gibi hizmetler bulunur.
J2ME (MICRO EDITION): Bu platform, 1991 yılında tanıtılıp kullanılmaya
başlanmıştır. Genellikle mobil cihazlar için kullanılan J2ME teknolojileri,
bunun yanında akıllı kartlar, avuç içi bilgisayarlar, kablosuz ve küçük cihazlar
için de kullanılır.
J2SE (STANDART EDITION): Çok gelişmiş uygulamaların haricinde,
kişisel bilgisayarlarda geliştirilen uygulamalardır. J2EE kullanılarak geliştirilen
uygulamalar gibi gelişmiş uygulamalar hazırlamaya elverişli değildir. Fakat
J2EE ile uygulama geliştirmek için sağlam bir J2SE bilginizin olması gerekir.
J2SE, J2EE kadar karmaşık bir yapıya sahip değildir.
Ders 2 - JDK Kurulumu
Java uygulamaları geliştirmek için bilgisayarınızda JDK'nın kurulu olması
gerekmekte. Bunun için JDK'nın herhangi bir sürümünü indiriyoruz. Biz
derslerimizde uygulamalarımızı J2SE teknolojisi ile yapacağımız için JDK'nın
J2SE için olan sürümlerini indirmemiz gerekiyor. Bunun
için http://adf.ly/YbRHk adresinden download'a tıklıyoruz ve anlaşmayı
onayladıktan sonra uygun işletim sistemini seçerek indiriyoruz. JDK
7 veya JDK 6sürümünü indirebilirsiniz.
PATH AYARLARI
Kurulumu yaptıktan sonra test etmek için Başlat simgesinden Çalıştır'a
tıkladıktan sonra, cmd yazıp konsol ekranına gitmemiz gerekiyor. Bunu
yaptıktan sonra konsol ekranına java yazalım ve Enter'a basalım. Bazı ayarların
geldiğini göreceksiniz. Daha sonra javac komutunu yazalım ve Enter'a
basalım. Path değişkenini tanımlamadıysanız, bu komut çalışmayacaktır. Bu
komutun çalışması için path tanıtmamız gerekiyor.
Bunu yapmak için şu adımları izleyelim.

Bilgisayarım'a sağ tıklayın.Özellikler - Gelişmiş - Ortam
Değişkenleri adımlarını izleyin

Kullanıcı Değişkenleri kısmında Yeni butonunu göreceksiniz.
Buraya, JDK'mızın kurulu olduğu dizini eklememiz gerekiyor.
JDK'nın kurulu olduğu dizin, eğer değiştirmediyseniz Program FilesJava-JavaJDK-bin klasörüdür.

Bu adresi kopyalayın (C:\Program
Files\Java\jdk1.7.0_45\bin indirdiğiniz sürüme göre değişebilir)

Daha sonra ilk anlattığım Kullanıcı
değişkenleri kısmında Yeni diyerek Değişken değeri kısmına
yapıştırıyoruz.

Değişken adı kısmına ise aynen path yazıyoruz.

Kullanıcı değişkenleri yerine Sistem
değişkenleri kısmından Yeni diyerek ve aynı parametreleri girerek de
yapılabilir. Sistem değişkenlerine eklersek, tüm kullanıcılar için
geçerli olur.

Son olarak Tamam diyerek çıkıyoruz.
Bu işlemleri yaptıktan sonra konsol ekranında javac komutunun artık çalıştığını
göreceksiniz. Peki, biz bupath değişkenini tanıtarak ne yaptık? Bir önceki
bölümde anlattığımız üzere Java kaynak kodları önce derlenerek byte koda
dönüştürülüyordu. Bunu javac derleyicisi yapıyor. Biz bu path değişkenini
tanıtmadığımız için javac komutu da çalışmadı. Artık bunu tanıttığımız için
programlarımız javac komutu ile derlenebilir. Ders
14'te path ve Classpath kavramlarını açıklayacağız.
JDK Kurulumumuz tamamdır. Şimdi ise IDE kurulumunu yapalım.
Ders 3 - Eclipse Kurulumu
Java programlarını geliştirebilmek için IDE'lere ihtiyaç vardır. Bunları
kullanmak zorunlu değildir, fakat program geliştirmede çok yardımcı olacaktır.
Bunları kurmadan da not defteri üzerinden program yazabiliriz, fakat IDE'ler
ile bu çok rahat olur. Not defteri ile yazmak çok zahmetlidir. Bu şekilde de
yazılabileceğini göstermek için bu bilgiyi verdik.
Java uygulamalarını geliştirmek için en önemli araç elbetteki IDE'dir. Bu her
programlama dili için vazgeçilmezdir. Java uygulamaları geliştirmek için
Eclipse programını kullanacağız. Eclipse eklenti bakımından çok zengindir.
Java uygulamaları için bize göre en iyi IDE, Eclipse'dir. Zaten geliştiricilerin
çoğu bunu kullanmaktadır. Şimdi ilk olarak http://adf.ly/YbWjW adresinden en
üst kısımda bulunan Eclipse Standartversiyonunun sağında bulunan 32bit veya
64bit seçeneklerinden sisteminize uygun olanı seçin.
Daha sonra [Turkey] Linux Kullanicilari Dernegi (http) yazısına tıklayarak
indirme işlemini başlatın.
Bu işlemleri yaptıktan sonra indirme işlemi başlayacaktır.
Eclipse IDE'yi indirdikten sonra klasör içerisinde bulunan eclipse.exe dosyasını
çalıştıralım kurulum gerektirmeyen Eclipse açıldığında ilk olarak, yapılan
projelerin hangi klasör altında toplanacağını gösteren bir soru ile başlıyor.
Burada istersek default(varsayılan) olarak gelen Workspace klasörü ile devam
ederiz. Eğer başka bir klasör altında toplansın istiyorsak Browse diyerek bu
klasörü seçebiliriz. Aşağıda bulunan kutucuğu işaretlersek, her açılışta bunu
sormayacaktır. Fakat işaretlemezsek her açılışta hangi klasöre toplayayım diye
soracaktır. Artık IDE'miz hazır. Java ile program geliştirmeye başlayabiliriz.
Bir sonraki dersimizde Eclipse ortamını tanıyacağız.
Ders 4 - Eclipse Ortamını Tanıyalım
ECLIPSE ARAYÜZÜ
Eclipse arayüzü yaklaşık olarak 5 temel bölgede incelenir.
Bu resimde arayüzünün temel bileşenleri yer almaktadır.
Numaralandırılmış bölgelerin açıklamalarını yapalım.
1.
Bu bölge projelerimizin gösterildiği yerdir. Eklediğimiz bir proje
burada görünür. İstenildiği zaman buradan silinebilir.
2.
Bu alanda kodlarımızı yazacağız. Henüz üzerinde çalıştığımız bir proje
olmadığı için bu alan kapalıdır.
3.
Yazdığımız konsol uygulamalarının çıktısını bu alanda göreceğiz. Bu
alanda, uygulamalarımızdaki hataları da görebiliyoruz. Ayrıca Apache
Tomcat gibi web serverları da bu kısımdan ekleyebiliriz.
4.
Burası perspektif veya platform dediğimiz yerdir. Dilersek Java
EE veya DDMS platformlarına da geçebiliriz. Hangi platforma
geçersek, arayüzdeki temel bileşenler bizim için ayarlanacaktır. Yeni
perspektif eklemek için Window-Open Perspective kısmından farklı
perspektifler ekleyerek, ekranınızdaki panellerin buna göre
şekillenmesini sağlayabilirsiniz.
5.
Bu alan ise bizim menümüzdür. Buradan proje ile ilgili ayarlar
yapabilir, yardım alabilir, yeni eklenti yükleyebilir, proje oluşturup
silebilir ve bunun gibi daha birçok şeyi yapabiliriz.
Buradaki numaralandırılmış bölgeleri yanlışlıkla kapatırsak şu şekilde bunları
tekrar açabiliriz.
Menüdeki Window kısmından Show View alanına tıklayalım. Burada sağ
tarafta açılan panellerden birisine tıklayarak o paneli ekleyebiliriz. Eğer
istediğimiz panel burada yoksa Other diyerek listede olmayan başka bir panel
ekleyebiliriz. Aşağıda panel ekleme gösterilmiştir.
ECLIPSE İÇERİSİNDE JRE AYARLARI
Eclipse ile bir proje geliştirebilmek için öncelikle JRE'yi Eclipse'ye tanıtmamız
gerekiyor. Bunun için;
1.
Eclipse açıkken Windows - Preferences dedikten sonra karşımıza
şöyle bir ekran gelecektir.
2.
Burada sol tarafta Java sekmesi altında Installed JRE'se tıklayalım.
Buradaki alan eğer doluysa yapmanız gereken bir işlem yok fakat bu
alan boşsa buraya bir JRE eklememiz gerekiyor.
3.
Bunun için sağ tarafta bulunan Add butonuna tıklayalım.
4.
Daha sonra Standart VM'yi seçtikten sonra Next diyerek ilerleyelim.
Karşımıza aşağıdaki gibi bir alan gelecektir.
5.
JRE Home kısmında, Directory'e basarak JRE'nin kurulu olduğu
dizini gösteriyoruz. Bu dizini, eğer anlattığımız gibi JDK'yı
yüklediyseniz C:\Program Files\Java\jre7 olarak
belirleyebilirsiniz. Javaklasörünün altında hangi versiyon kurulu ise
onu işaretleyin. JRE Name kısmında JRE versiyonunu yazabilirsiniz
yine anlattığımız gibi yüklediyseniz jre7 yazmanız gerekiyor.
6.
Son olarak Finish diyerek bitiriyoruz.
ECLIPSE ILE PROJE OLUŞTURMA
Bize lazım olan temel alanları öğrendiğimize göre artık yeni bir proje
oluşturabiliriz. Yeni bir Projeoluşturmak için:
File - New - Java Project adımlarını izliyoruz. Bundan sonra karşımıza
aşağıdaki gibi bir ekran gelecektir.
Buradaki numaralandırılmış yerleri de açıklayalım.
1.
Bu alana proje adını giriyoruz.
2.
Bu alanda kullanacağımız JRE'yi seçiyoruz. Alttaki seçeneklerde ise
kendimiz bir JRE ekleyebiliriz. Bunları yapmadan doğrudan 1.7
versiyonu ile başlayalım. Eğer 1.7 versiyonu seçili değilse
seçeneklerden JavaSE-1.7 versiyonunu seçebilirsiniz.
3.
Burada da projemiz için ayrı bir klasör oluştururuz. Daha sonra
göreceğimiz src ve bin dosyalarını oluşturarak projenin alt dosyalarına
ulaşabilmeyi kolaylaştırırız.
Daha sonra Next dedikten sonra karşımıza gelen ekrandan Finish diyerek
projemizi oluşturuyoruz. Buradaki alanları detaylı olarak Video kısmında
anlatacağız.
Sol tarafta Project Explorer içerisinde çıkan projemize çift tıklıyoruz. Alt
tarafta src ve JRE System Library adlı klasörler gelecektir.
Buradaki src klasörü içerisine projemizdeki sınıfları, panelleri, pencereleri ve
bunun gibi şeyleri ekleyeceğiz. JRE System Library içerisinde
ise jar dosyalarımız bulunur. Bu dosyalar bize hazır olarak gelir.
Bu jar dosyaları, programların çalışması için gerekli kütüphaneleri içerir.
Arayüz ile ilgili detaylı bilgileri aşağıdaki videoda daha detaylı olarak anlattım.
Dilerseniz inceleyebilirsiniz.
BİR PROJEYİ ECLIPSE İÇERİSİNE DAHİL ETME
Bir Java projesinde Eclipse içerisine Import edip bir proje üzerinde tekrar
çalışabiliriz. Bunun için yapmamız gerekenler şu şekildedir:
İlk olarak menü kısmından File - Import seçeneğine tıklıyoruz.
Tıkladıktan sonra gelen ekrandan General altındaki Existing Project into
Workspace kısmına tıklayarak ilerleyin. Bir proje eklemek istediğimiz için bu
kısma tıkladık. Ne eklemek istiyorsak ona uygun olan seçeneği işaretlememiz
gerekiyor.
Bu kısımda da Browse diyerek, projemizin bilgisayardaki yolunu seçiyoruz ve
projemiz alt kısma ekleniyor. Finish diyerek projeyi, Eclipse içerisine dahil
ediyoruz.
Projemizin, Project Explorer içerisindeki görünümü ise şu şekildedir.
ECLIPSE KISAYOLLARI
Bu dersimizde Eclipse içerisindeki en çok kullanılan kısayolları anlatacağız.

Ctrl+N> "Yeni" penceresini açar.

Ctrl+S> O an bulunan sayfayı kaydeder.

F11> Uygulamayı Debug yapmaya yarar.

Ctrl+F11> Uygulamayı derler ve çalıştırır.

Ctrl+Shift+O> Uygulamanızdaki import edilmemiş sınıfları otomatik
olarak import eder. Örneğin; matematik sınıfını kullanarak bir kod
yazdık fakat Math sınıfını uygulamamıza import etmemiz gerekiyor.
Bu kısayol, bu işlemi otomatik olarak yapar.

Alt+Up / Alt+Down> O anda bulunan satırdaki kodları, aşağı ve
yukarı taşımaya yarar. Kes-yapıştır işleminden bizi kurtarır.

Ctrl+R> Verilen satır sayısına dallanmaya yarar.

Ctrl+D> O an bulunulan satırı siler.

Ctrl+/> O an bulunulan satırı açıklama satırına çevirir.

Ctrl+\> O an bulunulan açıklama satırını kod satırına çevirir.

F14> Projemizin hiyerarşisini gösterir.

Shift+Alt+R> İmlecin üzerinde bulunduğu bir değişken, metod ve
sınıf ismini projenin tamamında aynı anda değiştirmeye yarar.

Ctrl+Space> Kodları otomatik olarak tamamlamaya yarar.
Kullanılan temel kısayollar bu şekildedir. Window-Preferences-General-Keys
kısmından bu kısayolları değiştirebilirsiniz.
JAVA UYGULAMASINI ECLIPSE DIŞINDA ÇALIŞTIRMA
Java projelerimizi Eclipse IDE dışında da çalıştırmamız mümkündür. Projemizi
Eclipse IDE dışında çalıştırmak için projeyi .jar dosyası olarak dışa
aktarmamız gerekmektedir. .jar formatı, Java uygulamalarının standart
formatıdır. Projemizi nasıl .jar dosyası olarak dışa aktarıldığını örnek üzerinden
inceleyelim.
Projemize sağ tıklayıp aşağıda şekilde gösterildiği gibi Export seçeneğini
seçin.
Açılan pencereden Java açılır seçeneğinin altından JAR File seçeneğini seçin
ve Next tuşuna basarak bir sonraki adıma geçin.
Açılan pencerede sol üst kısımdaki bölümden projemizi seçtikten sonra, aşağı
kısımda yer alan JAR Filebölümünden projemizin .jar dosyasının diskte
kaydedileceği alanı ve bu dosyanın ismini belirliyoruz. Bu bilgileri de girdikten
sonra Finish tuşuna basıp işlemi sonlandıralım.
Tüm işlemleri bitirdikten sonra belirlediğimiz yolun altında belirlediğimiz
isimle bir .jar dosyası oluştuğunu göreceğiz.
Bu .jar dosyasını Eclipse dışında çalıştırmak için konsola ihtiyacımız var.
Bunun için şu işlemleri yapın:
Windows komut istemcisini başlatın.(Çalıştır-cmd)
Daha sonra işlem(çıkış) klasörünüzü, cd dosyayolu komutu yardımıyla .jar
dosyasını kaydettiğiniz klasöre konumlandırın.(Bizim .jar dosyamız,
C:\Users\Okan\Desktop altında).
Programımızı çalıştırabilmemiz için .jar dosyamızı Java ClassPath'ine dahil
etmemiz gerekir. ClassPath, JavaRunTime kütüphanesinde mevcut sınıfları
tutar. Jar dosyanızı -jar komut satırına -jar parametresini girerek ClassPath'e
ekleyebilirsiniz.
Bu örnek için aşağıdaki kodları girdiğinizde resimdeki gibi bir sonuç elde
edeceğiz.
KOD: TÜMÜNÜ SEÇ
java -classpath proje.jar HelloWorld
//java -classpath <proje adı> <class adı>
Şekilde de görüldüğü gibi Java projemizi, Eclipse dışında başarıyla çalıştırmış
olduk.
Ders 5 - Java İle İlk Programımız
Temel şeyleri öğrendiğimize göre artık ilk Java programımızı yapabiliriz.
Bunun için Package Exploreriçerisinde daha önceden oluşturduğumuz
projedeki src klasörüne sağ tıklayıp New-Class dedikten sonra aşağıdaki
görüntü karşımıza gelecektir.
Şimdi buradaki alanları tanıyalım.
1.
Burada sınıfımızın olacağı paketi yazıyoruz. Bu konuyu paketler
dersinde detaylı olarak göreceğiz.
2.
Buraya da sınıfımızın ismini yazıyoruz. Alt tarafta bulunan final,
abstract gibi kavramları da işaretlemeyelim şimdilik. Bunları nesneye
yönelik programlama konusunda detaylı olarak inceleyeceğiz.
3.
Bu kısımda public static void main yeri işaretlediğimiz zaman bize
otomatik olarak, bir main metodu ekleyecektir. Alt taraftaki
kutucukları işaretlediğimiz zaman ise, yazılı olan alanları otomatik
olarak ekleyecektir. Şimdilik bunlara gerek yok.
İstenilen bilgileri oluşturduktan sonra Finish diyerek bitirelim. Bu adımları
yaptıktan sonra karşımıza aşağıdaki gibi bir kod ekranı gelecektir.
Burada dikkatimizi çeken bazı şeyler var.
İlk olarak Slash (/) dediğimiz işaretler bulunuyor. Bunlar Java'da açıklama
satırı için kullanılır. Açıklama satırları programımızda kodlara kısa
notlar düşmemize yardımcı olur. Bunlar derleyici tarafından derlenmez. Bu
kodlar, başkasının baktığında anlayabilmesi veya kodu yazan kişinin belli bir
zaman sonra tekrar baktığında ne yaptığını hatırlaması için kullanılır. Eğer tek
satırlık açıklama yapacaksak, açıklamanın başına sadece / getirmemiz yeterli
olacaktır. Birden fazla satır sürecekse, açıklama satırlarını /*...*/ arasına
yazmalıyız. Üç nokta ile gösterdiğimiz yere açıklama ekleriz.
Örnek verirsek:
//Bu bir açıklama
1
satırıdır.
2
/*Burası çok satırlı
3
açıklama satırıdır.*/
Burada bir main metodumuz bulunmaktadır. Programlar ilk olarak bu metod
içerisinden başlar. Bu metodstring tipinde bir args dizisini parametre olarak
alır. Bu parametreye Diziler konusunda detaylı olarak
değineceğiz. main metodunun başında static public void gibi anahtar kelimeler
vardır. Bunlara da Metodlarkonusunda değineceğiz.
Java'da herşey bir sınıf olduğu için ekrana bir şey yazdırmak için bile
bir sınıf oluşturmamız gerekiyor. Buradaki sınıfımızın adı JavaProgrami'dir.
Sınıf adı ile dosya adımız aynı olmalı. Sınıf kavramını da detaylı
olarakNesneye yönelik programlama konusunda anlatacağız.
Şimdi basit bir program yapalım. Bu programımızın
kodlarını main metodumuzun içerisine yazmamız gerekiyor. main metodunun
dışına da bir şeyler yazabilirsiniz fakat programı çalıştıracak
kodlar mainmetodunda bulunmalıdır. Mesela; main metodunun dışında
bir metod(fonksiyon) oluşturursak, bu metodu mainmetodu
içerisinden çağırmalıyız. İleride daha gelişmiş örnekler yapacağız.
Basit bir örnek olarak ekrana birşey yazdıralım. Karşımıza gelen açıklama
satırlarını da kaldıralım.
//JavaProgrami.java - 03.04.2014
1
2
public class JavaProgrami
3
{
4
public static void main(String[] args)
5
{
6
System.out.println("İlk Java
7
Programı");
8
}
9
}
10
11
Yazdığımız bu kodu, yukarıda yeşil renkteki butona basarak çalıştıralım. Dosya
adımıza sağ tıklayıp Run as - Java Application diyerek de çalıştırabiliriz.
Bu programın çıktısı aşağıdaki gibi olacaktır.
Ekrana bir yazı yazmak için System.out.println(); metodu kullanılır. Parantez
içerisine bir String veyadeğişken yazabiliriz.
System.out.println("İlk Java Programı"); //String
1
yazdırdık
2
System.out.println(a); //Değişken yazdırdık
Eğer String bir ifade yazdıracaksak çift tırnak içerisinde yazmalıyız. Bir
değişken yazacaksak, doğrudan o değişkeni eklemeliyiz. Peki,
hem değişken hem de String yazacaksak ne yapmamız gerekir? Bunu basit bir
örnekle anlayalım. Videolarımızda bol bol anlatacağız.
//JavaProgrami2.java - 04.04.2014
1
2
public class JavaProgrami2
3
{
4
public static void main(String[] args)
5
{
6
int a=5;
7
System.out.println(a+" Okan Bilke
8
ElektroArge");
9
System.out.println("Okan Bilke" + "
10 ElektroArge");
11
}
12 }
13
Bu kod, yukarıdaki gibi bir çıktı
verecektir. String ile değişkeni veya String ile String'i birleştirmek için +
operatörü kullanılır.
!
Istisnalar:
Java'da her ifade ; ile bitmek zorundadır.
INTELLISENSE TEKNOLOJİSİ
Intellisense dediğimiz teknoloji ile çoğu IDE'de bulunan özellik burada da
bulunmaktadır. Peki, bu özellik nedir ondan bahsedelim. Sys yazıp Ctrl tuşuna
basıp Space tuşuna bastığımızda Eclipse, bizim için Sys ile başlayan tüm
özellikleri getiriyor. Yapıldığında çıkan sonuç aşağıdaki gibi olacaktır.
Bu otomatik tamamlama özelliği, ileride değişkenleri, metodları, sınıf adlarını
ve bu gibi şeyleri kendisi tamamlayacaktır.
Ayrıca ekrana System.out. yazıp bu şekilde bıraktığımızda, kullanabileceğimiz
metodlar listelenecektir. Burada nokta (.)'ya bastığımız yerlerde, o sınıf
içerisinde kullanılabilecek metodlar gösterilir. Bunun bir örneği aşağıda
gösterilmiştir.
Ekrana bir şey yazdırma ile ilgili bir kısa yol verelim. Kod
yazarken sysout yazıp Ctrl ve Space tuşlarına basarsanız, otomatik
olarak System.out.println(); metodunu getirecektir. Bu metodun içerisine
istediğimiz şeyleri yazabiliriz.
NOT DEFTERİ İLE JAVA KODU YAZMA VE DERLEME
JDK Kurulumunu anlattığımız 2. Dersimizde javac komutuna değinmiştik
ve Not defteri ile programların yazılabileceğini, fakat gelişmiş programlar
yazmanın neredeyse imkansız olduğunu söylemiştik. Şimdi de dersimizin
başında yaptığımı örneği Not defterini kullanarak yapalım.
İlk olarak aşağıdaki kodu not defterine yazalım.
//Deneme.java - 04.04.2014
1
2
public class Deneme
3
{
4
public static void main(String[] args)
5
{
6
System.out.println("İlk Java
7
Programımız");
8
}
9
}
10
11
1.
Yazdıktan sonra uzantısını .java olacak şekilde Deneme.java adında
masaüstüne kaydediyoruz. Sınıf adı ile dosya adı aynı olmak
zorundadır. Kodumuzda sınıf adı Deneme olduğu
için Deneme adıyla kaydettik.
2.
Masaüstüne kaydettiğimiz bu .java uzantılı
dosyayı C:\Users\Okan klasörüne atalım. Bu sizde Okan değil de
başka bir klasördedir.
3.
Daha sonra Başlat'a cmd yazıp DOS ekranına geliyoruz.
4.
Burada javac Deneme.java yazıyoruz ve Enter tuşuna basıyoruz. Bu
işlem ile programımız javac derleyicisi ile derleniyor ve anlattığımız
gibi byte kod üretiliyor.
5.
Son olarak java Deneme yazıyoruz ve programımız çalışıyor.
Dos ekranındaki işlemler aşağıda gösterilmiştir.
Bu dosyayı C:\Users\Okan klasörüne atmamın nedeni şudur. DOS ekranında
kök dizinimizC:\Users\Okan klasörü olduğu için dosyanın da tanınması için bu
klasörde olması gereklidir. Bu klasör değil de başka bir klasöre atabilirdik. O
zaman DOS ekranında, o attığımız dizine gidip oradan çalıştırmamız gerekirdi.
Eğer Deneme.java dosyasını masaüstüne atsaydık ve masaüstünde çalıştırmak
isteseydik, konsol ekranında yazmamız gereken komutlar aşağıdaki gibi
olacaktı. Bu sayede DOS ekranından masaüstü dizinine gelip çalıştırmamız
gerekir.
Yukarıda java ve javac ile işlemler yaptık. javac ile .java uzantılı kaynak
kodlarımızı derledik. Sonunda.class uzantılı byte kodumuz oluştu. Bunu
ise java, yani JVM ile yorumladık. Bu byte kodları başka bir işletim sisteminde
yine JVM kullanarak yorumlayabilirdik.
Ders 6 - Eclipse Üzerinde Debug İşlemleri
DEBUG NEDİR?
Debug yapmak programın kaynak kodunun etkileşimli olarak çalıştırılması ve
bu esnada program değişkenlerinin durumlarının gözlemlenmesi ve bu sayede
hataları daha açık görmemize olanak sağlayan bir kod yürütme yöntemidir.
Break point'ler aracılığıyla kaynak kod işlenirken belirlenen satır işlendiğinde,
programın durmasını sağlayabilirsiniz veya Watch Point'ler aracılığıyla kaynak
kodunun belirli bir alanının çalışma esnasında alan okuduğunda veya
değiştiğinde o noktada programın durmasını sağlayabilirsiniz.
Programı bir noktada durdurduğunuzda işlenen satırdaki değişkenlerin
değerlerini gözlemleyebilirsiniz veya bu değişkenlerin içeriğini değiştirip farklı
bir değerle programın devam etmesini sağlayabilirsiniz.
Eclipse IDE, bize debug yapmak için özel bir görünüm sunuyor. Eclipse'nin
özel görünümü olan Debuggörünümünde önceden
belirlenmiş debug pencereleri vardır. Bu görünümde işlemin icrasını ve
değişkenlerin durumunu görmek daha kolay bir halde sunuluyor.
BREAKPOİNT YERLEŞTİRME
Kaynak kodumuzun belirli alanlarına breakpoint yerleştirerek programımızın
belirli alanlara geldiğinde durmasını sağlayabiliriz. Bu çoğu zaman problemin
nereden kaynaklandığı bulmak için başvurduğumuz yöntemlerden en sık
kullanılanıdır. Breakpoint yerleştirmek için Java kodunun herhangi bir satırına
resimdeki gibi Java kaynak kod düzenleyicisinin sol tarafındaki küçük alana
sağ tıklayın ve açılan pencerede Toggle Breakpoint seçeneğine tıklayın.
Basit şekilde ASCII tablosundaki büyük harfleri ekrana yazdıracağımız bu
örneğimizde;
1 karakter=(char)sayi;
... satırına breakpoint'imizi yerleştirdik. Java kaynak kod düzenleyicisinin
yanındaki küçük alana çift tıklayarak da breakpoint yerleştirebiliriz.
Java kodumuza breakpoint yerleştirdikten sonra, kodumuzu debug
yapabilmemiz için programımızıdebug modunda çalıştırmamız gerekmektedir.
Java kodumuzu debug modunda çalıştırabilmek için çalıştıracağınız projeyi sağ
tıkladıktan sonra, aşağıdaki şekilde gösterildiği gibi Debug As > Java
Applicationseçeneklerini seçin.
Eğer breakpoint tanımlamadıysanız program kodunuz debug modunda olmadan
normal bir şekilde çalışacaktır. Debug yapabilmek için breakpoint
yerleştirmeniz gerekmektedir.
Java kodunuzu debug modunda çalıştırdığınızda Eclipse size Debug
görünümüne geçmek isteyip istemediğinizi soracak.
Evet seçeneğini seçerseniz aşağıdaki resimdeki gibi bir görünümle
karşılaşacaksınız.
Java kodumuzu Debug modunda çalıştırdıktan sonra kodumuz belirli ölçülere
göre ilerleten tuşları kullanırız. Bu tuşlar ve görevleri aşağıdaki gibidir.
Tuş Açıklama
F5 Halen seçili olan satırı icra eder ve bir sonraki satıra geçer. Seçili satır metod tanımı ise metod
F6 Seçili satırı atlar ve bir sonraki satırı icra eder.
Metodu çağıran koda gider. Bu işlem icra edilen metodun sonlanmasını ve metodun kendisini
F7
sağlar.
Bir sonkrai Stop Point(Break Point veya Watch Point)'e kadar olan kodu icra eder ve kodun b
F8
durmasını sağlar.
Aşağıdaki şekilde bu tuşların Eclipse üzerindeki yeri belirtilmiştir.
BREAKPOİNT GÖRÜNÜMÜ VE BREAKPOİNT'LERİ KALDIRMA
Breakpoint görünümü bize Stop Point'leri devre dışı bırakmak, Stop Point'leri
kaldırmak ve bunlar üzerinde değişiklik yapmamızı sağlayan avantajlar sunar.
Şekilde görüldüğü gibi bir stop point'i devre dışı bırakmak için ilgili stop
point'in solundaki tik işareti kaldırılır. Tekrar tıklanıldığında stop point aktif
hale geçer. Stop point'leri silmek için resimde gösterildiği gibi tek bir stop point
silmek için stop point üzerine tıklanıldıktan sonra tek X işaretine basıldığında
ilgili stop point silinir. Çift X işaretine tıklanıldığında ise bütün stop
pointler silinir. Bütün stop point'leri devre dışı bırakmak için ise Skip All
Break Points tuşu kullanılabilir. Bu tuşa tekrar basıldığında bütün stop point'ler
tekrar aktif olacaktır.
DEĞERLER GÖRÜNÜMÜ VE DEĞİŞKENLERİN DEBUG MODUNDA
DEĞERLERİNİ DEĞİŞTİRME
Değerler görünümü, Java kodunda bulunan değişkenleri ve bunların aldığı anlık
değerleri gösterir. Değerler görünümü ve bu görüdümdeki değişkenler
aşağıdaki resimdeki gibidir.
Şekilde değişkenlerimizin ismini ve aldığı değerleri görüyoruz. Değişkenlerin
diğer özellikleri de bu görünümden görmek mümkündür. Bunun için aşağıdaki
resimdeki gibi görünüm penceresinin sağında kalan ok işaretine tıklanıldıktan
sonra açılan pencereden, Layout > Select Columns seçenekleri seçilerek açılan
pencereden değişkenlerin görüntülenen özellikleri arttırılabilir.
Değişkenlerin değerlerini değiştirmek için ise değeri değiştirilmek istenen
değişkenin Value özelliği tablodan çift tıklatılarak değiştirilir.
Ders 7 - Paket (Package) Kavramı
PAKET (PACKAGE) KAVRAMINA GİRİŞ
Package kavramı, Java kullanmamış olan kişilere başta yabancı gelebilir.
Package kavramını özetle tanımlayacak olursak, Java'da yazdığımız sınıflar
arasında bir hiyerarşi sağlar. Aslında Java programları da paketlerden oluşur.
Bu kavram, yazılım geliştirirken bize büyük kolaylık sağlar. Örneğin; bir
uygulama geliştiriyoruz diyelim. Bu uygulamamızda birçok modül var ve bu
modülleri tek bir dosya altında değil de bölümlere ayırarak bu modülleri tek bir
dosya altında değil de bölümlere ayırarak bu modülleri gruplayabiliriz.
Geliştireceğimiz uygulamalarda veritabanı işlemlerini ayrı bir pakette,
arayüzümüzü ayrı bir pakette gruplarsak daha yüksek performans elde
edebiliriz ve istediğimiz şeylere kolaylıkla ulaşabiliriz. Bu package, kavramını
marketlerdeki reyonlara benzetebiliriz.
Java paketinin içerisinde sınıflar ve arayüzler bulunur. Paketler, iyi bir
programcılık ve sistematik çalışma için gereklidir.
PAKET TANIMLAMASI
Java'da geliştireceğimiz uygulamalarda bir paket belirlemezsek; Java bizim
için default package adında bir paket oluşturur ve sınıflarımızı bu dosyada
tutar.
Paket tanımlamaları package anahtar sözcüğü ile şu şekilde yapılır:
package
1
com.org.veritabani;
Diyelim ki kütüphane ile ilgili bir projemiz olsun. Bu projede belirli alt
modüller olsun. Mesela; veritabanıve arayüz. Bu veritabanı modülü için
kullanmamız gereken paket kitap.veritabani; olmalıdır. Arayüz içinse bütün
sınıflarımızı kitap.arayuz; paketi altında toplamalıyız. Bunlar zorunlu değildir
tabi, fakat yapmak her zaman iyi olacaktır.
!
Istisnalar:
Paket tanımlamaları her zaman sayfamızın en üstünde olmalıdır.
Paket tanımlarken kullandığımız nokta(.) ile bir alt klasöre iniyoruz. Biz
genelde geliştirdiğimiz uygulamaları veya yaptığımız çalışmaları saklamak
için Belgelerim - Workspace adlı klasörü kullanıyoruz. Bu klasörde proje adı
ile saklanan çalışmalarımız vardır. Projemizin adının olduğu klasöre
girdiğimizde bin adında bir klasör daha bulunur. Burası bizim paketlerimizin
saklandığı yerdir. com.org.veritabani adında bir paket tanımladıysak,
bu bin klasörünün içerisinde com adında bir klasör, com klasörünün
altında org adında bir klasör daha vardır. Son olarak bu org klasörünün altında
da veritabani adında bir klasör daha vardır. Ne kadar nokta(.) koyarsak, o
kadar alt klasöre iner. Hiyerarşiyi bu nokta sağlar.
Paket adları, aynı zamanda klasör adlarına karşılık gelir. Nokta(.) ile
oluşturduğumuz her paket adı, hiyerarşik olarak alt dizinde bir klasör oluşturur.
Bir örnek verelim ve oluşan klasör yapısını görelim.
//Deneme.java - 04.04.2014
1
2
package kitap.deneme; //paket tanımlaması
3
yapıldı
4
5
public class Deneme
6
{
7
public static void main(String[] args)
8
{
9
Scanner s=new Scanner(System.in);
10
}
11
}
12
13
Paketi bu şekilde tanımlarsak klasör yapısı aşağıdaki gibi olacaktır.
Bu tanımlama ile resimde de görüldüğü gibi kitap ve deneme adında klasörler
oluşturulmuştur. Bunlar hiyerarşik olarak alt dizinlerde yer almaktadır.
Workspace dizininde Projemizin adının olduğu dosyaya
girdiğimizde bin klasörünün içerisinde bizim paket hiyerarşimiz yer alır.
Yine dediğimiz gibi bir a paketinin içerisinde b paketi varsa bu a.b ile gösterilir.
Paketlerle ilgili başka bir noktaya değinelim. Diyelim ki kitap1 adında bir
paketimiz var ve biz de herhangi bir sınıf üzerinde bir çalışma yapıyoruz. Bu
yaptığımız sınıfın üstünde kitap1 paketini tanımlarsak, bu sınıflar ve
arayüzler kitap1 paketine eklenir.
package kitap1; tanımlaması yaparsak, bunu derledikten sonra artık bu
sınıf kitap1 paketine eklenir.
Istisnalar:
!
Sınıfların aynı pakette olup olmadıkları önemlidir. İleride
göreceğimiz nesneye yönelik programlamakonusunda bunun
önemini göreceğiz. Temel olması için paket kavramından bu
dersimizde başlangıç düzeyinde bahsettik.
PAKETLERİ İMPORT ETME
Burada bahsedeceğimiz başka bir nokta da başka paketteki sınıfları nasıl
kullanacağımızdır. Bir paket içerisindeki herhangi bir sınıf üzerinde işlem
yapıyoruz ve bu sınıfta, başka paketteki sınıfa veya başka sınıflara ihtiyacımız
olabilir. Bunun için kullanacağımız paketi import etmemiz gerekir. Eğer bir
sınıfı import edeceksek...
1
import sınıfın_yolu;
... import anahtar kelimesini yazdıktan sonra sınıfımızın yolunu yazıyoruz.
Yoldan kastımız şudur: Diyelim kiveritabanı paketinin altında silme adındaki
sınıfı ekleyeceğiz. Bunun için:
1
import kitap.veritabani.silme;
Eğer bu veritabani adındaki paket altındaki birden fazla sınıfı kullanacaksak,
bunları tek tek eklemek yerine şu şekilde de yapabiliriz:
1
import kitap.veritabani.*;
Bu import ile veritabani altındaki tüm sınıfları import edebiliriz, yani tüm
sınıfları artık, bulunduğumuz sınıfın içerisinde kullanabiliriz. Bu olay C#
dilinde ve birkaç dilde de yapılabiliyor. Kullanılan anahtar kelime farklı olsa da
mantık aynıdır. Bu şekilde yapmak programı yavaşlatmaz, çünkü yine sadece
gerekli olan sınıf çalıştırılır.
Istisnalar:
!
import anahtar kelimesini, paket tanımlamasının bir alt satırında
kullanarak sınıflar ekleyebiliriz.
package ve import anahtar kelimelerinin kullanılmasına bir örnek verirsek, şu
şekilde bunları beraber kullanabiliriz.
//Deneme.java - 04.04.2014
1
2
package kitap.deneme; //paket tanımlaması
3
yapıldı
4
5
import java.util.Scanner; //Scanner sınıfı import
6
edildi
7
8
public class Deneme
9
{
10
public static void main(String[] args)
11
{
12
Scanner s = new Scanner(System.in);
13
}
14
}
15
Buradaki programımızı kitap klasörü altındaki deneme klasörünün içerisinde
oluşturduk. Workspaceiçerisindeki bu klasörlere baktığımızda, bu
programımızı görebiliriz. Paket tanımlamasını bu şekilde yaptık. Alt satırda
ise Scanner sınıfını import ettik. Yani dedik ki; bu programda Scanner
sınıflarını kullanacağız. Bunu C dilindeki include gibi düşünebiliriz. Bu sınıfı
programımıza dahil ettik.
Şimdi Java'da bizim kullandığımız hazır yazılmış paketlerden birkaçını
görelim...

java.lang: Bu ana paketimizdir diyebiliriz. Çünkü her Java
programında olması gereken bir pakettir. Bu yüzden bu paketi import
etmeye gerek yoktur. Yani her program şu paket eklenmiş olarak
gelir.java.lang.*;

java.util: Tarih, takvim gibi araçları kullanmamıza yarayan sınıflar
içerir.

java.io: Giriş Çıkış işlemleri için kullanılan sınıfları barındırır.

java.awt: GUI dediğimiz arayüzleri kullanmamıza yarar.

java.util.regex.*: Düzenli ifadeler eklemek için kullanılır.
Istisnalar:
!
Aynı paket içerisinde bulunan sınıflar, private elemanlar hariç
birbirlerinin diğer tüm elemanlarına erişebilir.private elemanları,
Nesneye yönelik programlama konusunda daha detaylı anlatacağız.
Ders 8 - Değişkenler ve Veri Tiplerine Giriş
Değişkenler, üzerinde veri depolayan sembolik isimlerdir. Verileri birbirinden
ayırmak için kullanılırlar. Nasıl insanları isimleri ile ayırt ediyorsak, verileri de
kendilerine ait bir değişken isimleri ile ayırırız. Her değişkenin bir tipi vardır.
Bu veri tipleri, değişkenlerin tanımlanmasında kullanılan primitive (temel) ve
nesne tanımlanmasında kullanılan referans tipleri olmak üzere 2'ye ayrılırlar.
Primitive tipler ile oluşturulmuş değişkenler, belleğin stack (yığın) kısmında
tutulurlar. Referans tipler ile oluşturulmuş değişkenler ise
belleğinheap alanında tutulurlar. Bu kavramları sonraki sayfalarda daha
ayrıntılı olarak anlatacağız.
Değişken Tanımlama Kuralı:
1
Özel_anahtar_kelime Veri_tipi degisken_adi;
1.
Özel anahtar kelimeler public, private, protected, static gibi anahtar
kelimeler olabilir. Bunları, nesneye yönelik programlamada daha
detaylı göreceğiz. Bunları yazmak zorunlu değildir. Eğer yazmazsak
public olarak kabul edilirler.
2.
Değişkenleri tanımlarken önce tipi yazılır. Daha sonra değişken
adı yazılır. Bunun için uyulması gereken kurallar da anlatılmıştır.
Değişkenlerin tanımlaması bu şekildedir.
Bir değişken tanımlama örneği verirsek;
int x; dediğimizde x adında bir değişken tanımlarız, fakat bir değeri yoktur.
Değeri atanmadığı için de bellekte bir yer kaplamaz.
Aşağıdaki gibi değişkeni tanımlayarak ona bir değer de verebiliriz.
Buna initialization denir.
int x=2; // değer atadığımız için bu değişkene bellekte bir yer
1
ayrıldı
!
Istisnalar:
Java'da tüm değişkenler, Java.lang sınıfından türemişlerdir.
Ders 9 - Değişken Tanımlama Kuralları
Değişken tanımlanırken uyulması gereken birkaç kurallar ve farklı tanımlama
alternatifleri vardır. Bu kurallar programlama dillerinde farklılık gösterir. Biz
burada Java'daki kuralları inceleyeceğiz.
1.
Her değişken bir tipe sahip olmalıdır.
Bir değişkenin sahip olacağı veri tipini tanımlamazsak hata ile
karşılaşırız.
a=10; // a cannot be resolved to a variable hatası
1
verilir
2
System.out.println(a);
2.
Değişkenler, değer atanmadan kullanılamazlar.
Bir değişken, değeri atamadan ekrana yazdırılamaz. Bunu
yaptığımızda hata alırız.
int a;
1
System.out.println(a); // The local variable a may not have been
2
initialized
3.
Aynıı tip değişkenler, aynı satırda tanımlanabilir.
Aynı tipte değişkenler tanımlayacaksak, aralara virgül koyarak tek
satırda tanımlayabiliriz.
String a="Okan", b="Onur", c="ElektroArge"; // a, b ve c değişkenleri
1
tanımlandı
4.
Değişken isimlerinde Türkçe karakter kullanılmamalıdır.
Değişken isimlerinde ı, ö, ü gibi Türkçe karakterler kullanılmamalıdır.
Hata vermese de bunları kullanmak uygun değildir.
String ö="Okan", ı="ElektroArge"; // Hata vermeyecektir, fakat dikkat
1
edilmelidir.
5.
Değişken isimleri sayı ile başlayamaz ve değişken isminde boşluk
olmamalıdır.
Değişken isimleri sayı ile başlayamaz, fakat _,$ gibi bazı işaretlerle
başlayabilir.
1
int $x; // doğru kullanım
2
int _b; // doğru kullanım
3
String degisken adi="Okan Bilke"; // hata verir
4
String 1soyadi="ElektroArge"; // hata verir
Istisnalar:
!
Java, Case Sensitive bir dildir. Yani büyük küçük harf ayrımı
vardır. A ile a değişkeni farklıdır.
Istisnalar:
!
Verilerimizi değişkenler ile tanıdığımız için değişken isimlerinin
anlamlı olmasına dikkat etmeliyiz. Bu, programımızın
anlaşılabilirliğini artırır. Kısa programlar için bu çok önemli değildir.
Değişken kavramını öğrendiğimize göre şimdi bu değişkenlerin tiplerini
inceleyelim. primitive vereferans tipleri olmak üzere 2 veri tipimiz vardır.
Şimdi bunları görelim.
Ders 10 - Primitif Tipler
BYTE
8 bittir. Bellekte 1 byte yer kaplar. Tamsayı türünde -128 ile 127 arasında
değerler alır. Küçük değerli sayılar için, int yerine kullanılabilir. Varsayılan
değeri 0'dır.
byte a=5;
1
byte b=125; // Eğer b'ye 130 verseydik, 12 üst sınırını aşacağından hata
2
verecekti
3
System.out.println(a+b);
Istisnalar:
!
Bu sayı tiplerinde bir bit, işaret biti
olarak kullanılır.
Istisnalar:
!
Veri tiplerinin varsayılan değerleri, o tipten tanımlanmış bir değişkene
değer atanmadığında kullanılan değerdir.
SHORT
16 bittir. Byte tipindekilerden daha büyük sayılar alabilir. Tamsayı türünde 32768 ile 32767 arasında değerler alır. Varsayılan değeri 0'dır.
short sayi=32767; // bu değerden daha fazlasını alırsa hata
1
verir
2
System.out.println(sayi);
INT
32 bittir. Bellekte 4 byte yer kaplar. Tamsayı türünde -231 ile 231-1 arasında
değerler alır. Varsayılan değeri 0'dır.
1 int sayi=1453;
2 System.out.println(sayi);
LONG
Uzunluğu 64 bittir. Tamsayı türünde -263 ile 263-1 arasında değerler alır.
Varsayılan değeri 0L'dir.
long y=666666399;
1
long z=y*y;
2
System.out.println(z); // değişkeni int olsaydı, bu değer
3
tutulamazdı
FLOAT
Uzunluğu 32 bittir. Ondalık sayı türünde -3.4*1038 ile 3.4*1038 arasında
değerler alır. Varsayılan değeri 0.0f'dir.
1
float a=-5;
2
float b=a/100;
3
System.out.println(b);
DOUBLE
Uzunluğu 64 bittir. Ondalık sayı türünde -1.7*10308 ile 1.7*10308 arasında
değerler alır. Varsayılan değeri 0.0d'dir.
1
double sayi=5.111;
2
double sayi2=sayi/2012;
3
System.out.println(sayi2);
Istisnalar:
!
Java'da ondalık sayı türünde 2 tane veri tipi vardır.
Bunlar; float ve double'dır. Bilgisayarda ondalık sayıları tutabilmek
için Java, IEEE 754 standardını kullanır.
CHAR
Uzunluğu 16 bittir. Karakter türünde değerler alır. İçerisinde yalnızca bir
harf, rakam veya işaretgirilebilir. Girilen bu değerler çift tırnak değil tek
tırnak arasına yazılmalıdır. Bu veri tipinde de büyüktür - küçüktür gibi
karşılaştırmalar da yapılabilir. Varsayılan değeri \u0000'dır.
char deger1='M';
1
char deger2='-';
2
char deger3='8'; // 88 yazsaydık hata verecekti
3
System.out.println(deger1+" "+deger2+"
4
"+deger3);
Şu kullanım yanlıştır:
1
char deger = 'xy'; // hatalı kullanım. tek değer alabilir.
BOOLEAN
Yalnızca 2 değer alır (true veya false). Bellekte 1 bit yer kaplarlar. Varsayılan
değeri false'dur.
int a=5;
int b=6;
boolean x=(a==b);
//a ile b karşılaştırılır. a ile b eşit olmadığı için false döner ve bu x'e
atanır.
System.out.println(x);
1
2
3
4
5
Istisnalar:
!
Kullanacağımız değer, hangi veri tipine uygunsa onu kullanmalıyız.
Değerimiz 50 ise bunu byte tipinde tutmak daha uygun olacaktır. Aksi
halde int tipinde tutarsak, bellekte fazla yer kullanılmış olur.
Istisnalar:
!
JavaSE-7 ile gelen yenilikle beraber sayısal veri tipleri
içerisinde altçizgi (_) kullanılabilmektedir.
Ders 11 - Referans Tipler
Array, Class ve Interface olarak tutabileceğimiz 3 referans tipi vardır. Bunlara
girmeden sadecedeğişkenler kısmına bakalım.
Referans tiplerde, değişkenlerin adresleri tutulur. Referans tipler, new anahtar
sözcüğü ile tanımlanırlar. Referans tipler, belleğin heap alanında tutulurlar.
Referans tiplerinde, primitive tiplerden farklı olarak işlemler değişkenin
kendisi ile yapılır. Yani primitive değişkenlerdeki gibi kopya üzerinden değil
orjinal değer üzerinden işlem yapıldığı için değeri değişir.
Şimdi bir örnek yapalım ve farkı görelim.
1
//VeriTipleri.java - 04.04.2014
2
3
public class VeriTipleri
4
{
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args)
{
Deneme d = new Deneme();
d.x=50;
System.out.println("Sayının ilk değeri
:"+d.x);
carp(d);
System.out.println("Sayının ilk değeri
:"+d.x);
}
public static void carp(Deneme d)
{
d.x=d.x*2;
}
}
class Deneme
{
public int x;
}
Bu konuda değişkenleri anlatıyoruz, fakat sınıflardan türetme ve nesne gibi
olayları anlatmak zorunda kaldık. Nesneye yönelik programlamayı öğrendikten
sonra, tekrar bu dersimize göz atabilirsiniz.
Burada ddeğişkenini Deneme sınıfından oluşturduk. Deneme sınıfında ise bir
değişkenimiz var. Bu değişkene d.x=50diyerek değer atadık ve
doğrudan carp() metoduna gönderdik. Burada d.x değişkenimiz yeni bir değer
aldı ve artık d.x değerimiz 100 oldu. Eğer kopyası gönderilseydi,
yine 50 sayısını elde edecektik. Referans tiplerde değişkenlerin bellekteki
adresleri tutulduğundan orjinal değeri de değişir.
STRING VERİ TİPİ
string, referans tipindedir. string tipi için, char'ların birleşmesinden oluşmuştur
diyebiliriz. char'dan farklı olarak çift tırnak içerisinde tanımlanırlar.
Karakter dizilerinin birleşmesinden oluşmuştur.
String yazi="Okan Bilke";
1
String yazi2="ElektroArge";
2
System.out.println(yazi+" 3
"+yazi2);
String ifadeleri, çift tırnak içerisinde tanımlanır. Bir string değere, başka
bir string değer eklenebilir. Bunlar tek bir değişkende toplanabileceği gibi
yukarıdaki gibi ayrı ayrı birleştirilerek de yazılabilir.
Bir string değişkeninin değerinin değiştirilmesine örnek verelim.
//Degiskenler.java - 04.04.2014
1
2
package com.org.degiskenler;
3
4
public class Degiskenler
5
{
6
public static void main(String[]
7
args)
8
{
9
String deneme="Elektroarge";
10
deneme=deneme+" Java
11
Dersleri";
12
System.out.println(deneme);
13
}
14
}
15
deneme adlı değişkene bir ekleme yaptık ve sonucu ekrana yazdırdık.
Eklemeleri + operatörü ile yaptık.
PRİMİTİVE TİPLERİ, REFERANS TİPİ ŞEKLİNDE YAZMA
Bir değişken, ilkel olarak tanımlanmasının yanında o veri tipinin sınıfı ile de
tanımlanabilir. Değişkenlerin veri tipleri, aynı zamanda bir sınıf'tır. Bu da
demek oluyor ki bilinen şekilde değişkenleri tanımlamanın yanında,sınıftan
türetilen bir nesne şeklinde de tanımlayabiliriz. Bunu bir örnek üzerinde
gösterelim.
//Degiskenler2.java - 04.04.2014
1
2
package com.org.degiskenler;
3
4
public class Degiskenler2
5
{
6
public static void main(String[] args)
7
{
8
int i=5; // primitive tipteki değişken
9
Integer j=new Integer(6); // referans tipindeki
10
değişken
11
System.out.println(i);
12
System.out.println(j);
13
}
14
}
15
16
int i olarak tanımladığımız bir değişkeni, Integer sınıfından türetilen
bir nesne aracılığıyla da türetebiliriz. Burada i değişkeninin
değeri 5, j değişkeninin değeri ise 6 olmuştur. Sadece int değil, tüm veri
tiplerinde bu geçerlidir.
Başka bir örnek verirsek;
//Degiskenler3.java - 04.04.2014
1
2
package com.org.degiskenler;
3
4
public class Degiskenler3
5
{
6
public static void main(String[] args)
7
{
8
int i=3; // yerel değişken
9
Integer j=new Integer(4); // referans tipteki değişken
10
String s="Okan Bilke"; // yerel değişken
11
String s1=new String("ElektroArge"); // referans tipteki
12
değişken
13
double x=457.2; // yerel değişken
14
Double y=new Double(378.3); // referans tipteki değişken
15
System.out.println(i);
16
System.out.println(j);
17
System.out.println(s);
18
System.out.println(s1);
19
System.out.println(x);
20
System.out.println(y);
21
}
22
}
23
24
Referans tipteki değişkenleri görüldüğü gibi new ile oluşturduk. Bu şekilde
tanımlama yapmanın arasında belirli farklar vardır. Dediğimiz
gibi primitive ve referans tipleri arasındaki farklar burada da geçerlidir.
Normal değişken tanımlaması yaptığımızda, bu değişken
belleğin stack kısmında tutulur. Aynı değişkeni nesne türeterek
tanımladığımızda ise heap alanında tutulur.
Bunlardan yola çıkarak şunu diyebiliriz ki; int veri tipi, Integer sınıfının bir
öğesidir. Yani Integer sınıfı,int tipini sarmalar. Buna wrapper denir. Bu
sadece int tipinde değil tüm veri tiplerinde geçerlidir.
Buradaki integer ve int tipinde değişken tanımlamadaki farkların birkaçından
daha bahsedecek olursak şunları söyleyebiliriz:
1.
Integer tipinde tanımlanmış bir değişken, java.lang.Integer sınıfının
metodlarını kullanabilirken inttipinde tanımlanmış değişken bunları
kullanamaz.
2.
Primitive değişkenler(int, byte vs.) serileştirme işlemine tabi
tutulamazlar. Bunu daha sonra göreceğiz.
3.
Integer tipindeki bir değişkene null değerini verebiliriz,
fakat int tipinde bu mümkün değildir.
Ders 12 - Boxing ve Unboxing Kavramı
Anlattığımız gibi bu değişkenler hem primitive olarak tanımlanır hem
de bunun sınıflarındantanımlanabilir. Bu şekilde primitive tiplerin, bu sınıflar
içerisine gömülmesine kutulama(boxing) denir. Bunun tersi olarak da sınıf
nesnelerinin ilkel tiplere dönüştürülmesine de kutu açma(unboxing) denir.
Bunları derleyici otomatik olarak yapar.
Bunlara örnek verirsek:
public static void main(String[]
1
args)
2
{
3
int a=5;
4
Integer b=new Integer (a); //
5
Boxing
6
int y=b.intValue(); //Unboxing
}
Tip dönüşümleri konusunu öğrendikten sonra
bu unboxing ve boxing işlemlerini daha iyi anlayabilirsiniz. Bu işlemler Java
5.0'da otomatik olarak yapılıyor. Normalde b değişkeni bir nesne olduğu için
bunun değerini artıramayız. Bunu yapabilmek için boxing işlemine ihtiyaç
vardır. Yani bunu ilkel bir tipe dönüştürmeliyiz. Daha sonra ihtiyaca göre tekrar
referans tipine dönüştürebiliriz. Bu gibi işlemler
için boxing ve unboxing kullanılır.
Ders 13 - Lokal Değişkenler
Oluşturduğumuz programlarda 3 tip değişken bulunur. Bunlar orjinal
isimleriyle local variables, classvariables ve instance variables'dir. Sınıf (class)
değişkenlerini, nesneye yönelik programlama dersinde
anlatacağız. Instance değişkenler ise sınıf içerisinde, fakat metodların
dışında tanımlanır. Bunlara nesnedeğişkenleri de denir. Her nesne için ayrı ayrı
oluşturulur. Bu da nesneye yönelik programlama dersinde anlatılacaktır. Bu
başlık altında lokal değişkenleri inceleyeceğiz.
Döngü içerisinde veya bir metod içerisinde tanımladığımız değişkenlerin yaşam
süresi, o döngü veya metod bloklarından çıkana kadardır. Bloktan çıktığı zaman
değişkenin sakladığı değer kaybolur. Burada tanımladığımız bir değişkene
dışardan erişemeyiz. Bunlara lokal değişkenler denir.
Bir metodun içerisinde tanımladığımız i değişkeni ile başka bir metodda
tanımladığımız i değişkenleri birbirinden bağımsızdır. Herhangi birinde
yapacağımız değişiklik diğer değişkeni etkilemez. Local değişkenlere bir örnek
verelim.
//Degiskenler.java - 04.04.2014
1
2
package com.org.degiskenler;
3
4
public class Degiskenler
5
{
6
public static void main(String[] args)
7
{
8
for(int i=0;i<5;i++)
9
{
10
int toplam=1;
11
toplam+=toplam;
12
}
13
System.out.println(toplam);
14
//erişilemez
15
}
16
}
17
18
Bu örnekte toplam değişkeni for döngüsü içerisinde tanımlandığı için döngüden
çıkıldığı anda değeri kaybolur ve bellekten silinir. Bu döngü dışında değişkene
erişmeye çalıştığımızda hata alacağız.
Bu örnekte döngüleri kullandık. Bunun tanında metodlar içerisinde de yerel
değişkenler kullanımına örnek verelim.
//Degiskenler2.java - 04.04.2014
1
2
package com.org.degiskenler;
3
4
public class Degiskenler2
5
{
6
public static void main(String[]
7
args)
8
{
9
int sayi=4;
10
metod(sayi);
11
System.out.println(sayi);
12
}
13
static void metod(int sayi)
14
{
15
sayi=sayi*5;
16
}
17
}
18
19
Bu örnekte sayımızı 5 ile çarptık, fakat sonuç olarak 4 değeri döndü. Çünkü
biz sayi değişkenimizi yerelolarak tanımladık. Bir metod içerisinde, o sayıyı 5
ile çarpsak da metoddan çıkınca, sayımız yine eski değerine döndü.
Ders 14 - Sabit Tanımlama
Sabitler, değeri değiştirilemeyen değişkenler için kullanılır. Programımızın
herhangi bir yerinde değerinin değişmesini istemediğimiz
değişkenleri sabit olarak tanımlarız.
Java'da sabit tanımlama final anahtar kelimesi ile yapılmaktadır. Bu anahtar
kelimenin birçok görevi bulunmaktadır. Biz burada sadece sabitler
tanımlamasını anlatacağız. Diğer görevlerini ve final anahtar kelimesinin
detaylı anlatımını, Kalıtım bölümünde inceledik.
Sabitler ile ilgili söyleyeceğimiz ilk şey, bu değişkenlerin ilk değer
atanması zorunluluğu vardır. İlk değerleri atanmadan kullanılamazlar. Ya
tanımlandığı ilk anda değeri verilecek ya da yapıcılar ile değeri atanacak.
Sabit tanımlamak için değişkenimizin başına final anahtar kelimesini
getiriyoruz.
Örnek sabit tanımlaması
final int x=5; // final ile sabit
1
tanımlaması
Eğer ilk değer ataması yapmasaydık, yani aşağıdaki gibi bir kullanım yapsaydık
hata alacaktık.
final String ad;
1
System.out.println(ad); // hata alırız. ilk değer
2
verilmedi
Sabitleri tanımlayıp başka satırda ilk değer vermeye çalışırsak da hata alırız.
Eğer sabitimizi metod içerisinde tanımlamadıysak, tanımlandığı satırda değeri
verilmelidir. Örnek verirsek;
1
final String a;
2
a="Deneme"; // hatalı kullanımdır
Burada bir istisna vardır. Sabitimizi eğer bir metod içerisinde
tanımladıysak, başka bir satırda da ilk değer verebiliriz. Şimdi
hem main metodu içerisinde hem de metod dışarısında sabit tanımlayalım ve
farkını görelim.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Degiskenler.java - 04.04.2014
public class Degiskenler
{
final String x1; // metod dışında tanımlandı
x1="Metod dışında"; // hatalıdır
public static void main(String[] args)
{
final String x2; // metod içinde tanımlandı
x2="Metod İçinde"; // başka satırda da ilk değer
atanabilir
}
}
Yukarıdaki örneğimizde metod içinde ve dışında sabit tanımladık. Metod içinde
tanımlarsak, ilk değerini alt satırda da verebiliriz. main de bir metod olduğu
için, programımızın başladığı bu yerde de tanımlama yaparsak başka satırda ilk
değerini verebiliriz.
Sabitlerin değerinin başka bir yerde değiştirilemeyeceğini söylemiştik. Bu
şekilde hatalı bir kullanıma örnek verelim ve sabitimizi başka bir yerde
değiştirmeye çalışalım.
final byte sayi=4;
1
System.out.println(sayi);
2
sayi=40; // sabitlerin değeri
3
değiştirilemez
Sabitlere en iyi örnek PI sayısı verilebilir. Sabitlere ilk değer vermenin diğer
yolu da yapıcılarkullanmaktır. Bu yöntemi ise Kalıtım dersinde anlatacağız.
Bunun için yapıcının da ne olduğunu bilmemiz gerekiyor. final anahtar
kelimesinin detaylı kullanımı, Kalıtım dersinde daha detaylı işlenmiştir.
Ders 15 - Tip Dönüşümleri
Veri tipleri konusunu görmüştük. Kullanım amaçlarına göre farklı veri tipleri
vardır. Bu veri tipleri arasında bir dönüşüm ihtiyacı hissedebiliriz. Mesela, nasıl
bir ihtiyaç?
Diyelim ki kullanıcıdan bir sayı aldık. Bu sayı ile matematiksel işlemler
yapmak istiyorsak, bu sayıyı int tipine dönüştürmemiz gerekir. Çünkü
kullanıcının girdiği sayı, string tipinde alınır. Başka bir örnek verirsek, küsüratlı
bir sayının küsüratlarını almak için de kullanabiliriz.
Istisnalar:
!
Bir değişkeni kendinden daha büyük tipteki
değişkenlere cast ettiğimizde, veri kaybı olmaz. Fakat kendinden daha
küçük tipteki bir değişkene cast ettiğimizde, veri kaybı olabilir. Bunu
bir valizdeki eşyaların, daha küçük boyuttaki bir valize yerleştirilmesi
gibi düşünebiliriz.
İlk olarak string int tipine dönüştürmeyi görelim. Bunun için 2 yol vardır.
Bunlar parseInt ve valueOfmetodlarıdır.
String degisken="5";
1
int
2
yeni1=Integer.valueOf(degisken);
3
int
yeni2=Integer.parseInt(degisken);
Burada 5 sayısını string olarak tanımladık. Bunun üzerinde matematiksel işlem
yapabilmek için bunu inttipine cast etmemiz gerekiyor. Bunun
için Integer sınıfının 2 metodu kullanabiliriz. Bu her iki metod da sayımızıint'e
çevirir. Fakat arasında bazı farklar var. valueOf metodu, parseInt metoduna
göre daha yavaştır. AyrıcaparseInt metodu int tipinde bir veri tipi döndürürken,
valueOf metodu ise integer tipinde bir nesne döndürür. Bir örnek verelim:
Eğer bu örnekte degisken adlı değişkenimiz int tipine cast etmeseydik, üzerinde
sayısal işlem yapamazdık.
Şimdi ise int tipinden string tipine cast işlemini görelim. Bunun için de 2
yöntem vardır. İlki Stringsınıfının valueOf metodudur. Diğeri
ise Integer sınıfının toString metodudur.
Görüldüğü gibi 2 şekilde de int tipindeki değişkeni string tipine cast ettik.
Buradaki metodlarımız içerisine, cast edeceğimiz değişkeni yazıyoruz. Son
olarak da göstermek için ekrana yazdırdık.
Konuyu anlatırken cast işlemindeki amacın küsuratları yok etmek olduğunu
söylemiştik. Bunun için kullanılan cast işlemleri de vardır. Buna örnek
olarak double tipini int tipine dönüştürmeyi örnek verebiliriz.
//Degiskenler.java - 04.04.2014
1
2
public class Degiskenler
3
{
4
public static void main(String[]
5
args)
6
{
7
double sayi=345.2;
8
int sayi2=(int)sayi;
9
System.out.println(sayi2);
10
}
11
}
12
13
Burada double sayımızı int'e cast ettik. Bunun için değişkenin başına (int)
koymamız yeterli. Gördüğünüz gibi int tipinde küsürat olmadığı için sadece
tamsayı olan kısmını aldık.
Şimdi ise tam tersi, int tipinden double tipine cast işlemi yapalım.
Burada da int tipindeki değişkenimizin başına (double) yazmak yeterli
oldu. double tipinde virgülden sonraki kısım olduğu için otomatik
olarak 0 sayısını koydu ve ekrana 345.0 yazdı.
Aynı şekilde float tipinden long tipine cast işlemi ise:
Burada da küsüratları yok etme işlemi yaptık, fakat sadece veri tiplerimiz
farklı float veri tipi ondalıklı,long tipi ise tamsayı türünde olduğu için sonuç da
bir tamsayı oldu ve küsuratlar kaldırıldı. Bunun da tersini görelim.
long tipinden float tipine bir cast işlemi yaptığımızda da sonuna küsuratlar
geliyor. Çünkü sonuç bir ondalık olmalı. Bunun sebebi de float'a dönüştürme
yapmamızdır. float da bir ondalık sayı türüdür.
Dönüştürme işlemlerinde son olarak diğer tiplerdeki değişkenleri, string veri
tipine dönüştürmeyi anlatalım.
//Degiskenler.java - 04.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Degiskenler2
{
public static void main(String[] args)
{
long a=456363;
String deger1=String.valueOf(a); //
yöntem 1
String deger2=Long.toString(a); //
yöntem 2
float b = 311.123f;
String deger3=String.valueOf(b); //
yöntem 1
String deger4=Float.toString(b); //
yöntem 2
byte c=11;
String deger5=String.valueOf(c); //
yöntem 1
String deger6=Byte.toString(c); //
yöntem 2
}
}
Son örneğimizde ise diğer veri tiplerini, string veri tipine cast etmeyi anlattık.
Her biri için iki yöntem var. Birisi String sınıfının metodu, diğeri ise veri
tiplerinin kendisine ait sınıfının metodudur.
Ders 16 - Java'da Kullanılan Anahtar Kelimeler
Java'da kullanılan anahtar kelimeleri aşağıda listeledik. Bunları derslerimizde
anlatacağız.
abstract
assert
boolean
break
byte
case
catch
char
class
const
continue
default
do
double
else
enum
extends
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
navite
new
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
throw
throws
transient
try
void
volatile
while
Bu anahtar kelimelerin tamamı küçük harfle yazılır. goto ve const artık
kullanılmıyor olsa da, Java içerisinde bulunurlar.
Ders 17 - Operatörlere Giriş
Yazacağımız uygulamalarda gerek matematiksel, gerekse karşılaştırma gibi
işlemler yapmak isteyebiliriz. Bunlar bir yazılım için olmazsa olmazlardandır.
Örnek verirsek, bir login işleminde kullanıcının girdiği kullanıcı
adı ve şifre değerlerinin, veritabanındaki değerleri ile karşılaştırılması gerekir.
Hem kullanıcı adı hem deşifrenin uyması durumunda login işlemi tamamlanır.
Bunlar her yazılım dilinde operatörler ile sağlanır. Bunların yanında birçok
temel işlem operatörler ile yapılır. Şimdi Java'da hangi operatörlerin olduğuna
değinelim.
Ders 18 - Atama Operatörleri
Atama operatörleri, bir değişkeni başka bir değişkene atamak veya bir
değişkene bir değer atamak için kullanılır. Bu atama işlemi yapılırken, aynı
zamanda aritmetik operatörler de kullanılabilir. Temel atama operatörlerine
bir göz atalım.

= En temel atama operatörüdür. Atamalar her zaman sağdan
sola doğrudur.

+= Soldaki değere, kendi değeri ile beraber sağdaki değeri de
ekleyerek tekrar soldaki değere atar.

-= Soldaki değerden, sağdaki değeri çıkararak tekrar soldaki değere
atar.

*= Soldaki değeri, sağdaki değerle çarparak tekrar soldaki değere atar.

/= Soldaki değer, sağdaki değere bölerek sonucu tekrar soldaki değere
atar.
TEMEL ATAMA OPERATÖRÜ( = )
Temel atama işlemleri = operatörü ile yapılır. Sağdaki değer soldaki değişkene
atanır.
int a = 5; // a değişkenine 5 değerini atadık
1
int b = a; // b değişkenine a değişkeninin değerini
2
atadık
3
7 = a;
// hatalı atama. bir değişken, bir değere
atanamaz
Örnek üzerinde daha detaylı gösterirsek:
1
//Operatorler.java - 04.04.2014
2
3
public class Operatorler
4
{
5
public static void main(String[]
6
args)
7
{
8
String ad = "Mehmet";
9
int a = 5;
10
int c = a;
11
System.out.println(ad);
12
System.out.println(a);
13
14
15
16
System.out.println(c);
}
}
Ekran çıktısı:
1
Mehmet
2
5
3
5
DİĞER ATAMA OPERATÖRLERİ( +=, -=, *=, /= )
Bu operatörler, soldaki değerle sağdaki değeri işleme tabi tutar ve sonucu tekrar
soldaki değere atar. Aradaki operatör hangisi ise o işlem yapılır.
int a;
1
a = a + 5;//a değişkenine 5 değerini ekledik.Bunun kısa yolunu ise alttaki gibi
2
yapabiliriz
3
a += 5; //soldaki a değerine, sağdaki 5 değeri eklenerek tekrar a'ya atandı.
4
a *= 5; //a değeri 10 ile çarpılarak sonuç tekrar a değişkenine atandı.
Yukarıda int a; tanımlaması yaptığımız için artık bundan sonraki
tanımlarda a değişkeninin başına intyazmaya gerek kalmaz.
int a = 20;
1
a *= 5; // a = a * 5;
2
System.out.println(a); // bu kod yüz çıktısını
3
verecektir.
Bu operatörlere toplu bir örnek yapalım.
1
//Operatorler2.java - 04.04.2014
2
3
public class Operatorler2
4
{
5
public static void main(String[]
6
args)
7
{
8
int a = 10, b = 20, c = 100, d =
9
40;
10
a += 5;
11
b -= 25;
12
c *= 2;
13
d /= 10;
14
15
16
17
18
19
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
Ekran çıktısı:
1
15
2
-5
3
200
4
4
Buradaki 4 değişkenimizin yeni değerlerini çıktıda görüyoruz. Aradaki işaret ne
ise, ona göre işlem yapıldı ve sonuç tekrar soldaki değişkene atandı.
ÇOKLU ATAMA İŞLEMİ
Bir değeri diğerine atama işlemi, çoklu atama şeklinde de olabilir. Yani bir
değeri diğerine atarken, aynı zamanda bunu başka bir değere de atayabiliriz.
Buna bir örnek verelim.
//Operatorler3.java - 04.04.2014
1
2
public class Operatorler3
3
{
4
public static void main(String[]
5
args)
6
{
7
int sayi1 = 3;
8
int sayi2 = 5;
9
int k = sayi1 = sayi2;
10
System.out.println(k);
11
System.out.println(sayi1);
12
System.out.println(sayi2);
13
}
14
}
15
16
Ekran çıktısı:
1
5
2
3
5
5
Burada sayi2'yi sayi1'e atarken, sayi1'i de k değişkenine atmış oluyoruz.
Dolayısıyla en sağdaki değer olan sayi2, bütün değişkenlere birden atanmış
oluyor ve diğer değişkenler de sayi2'nin değerine sahip oluyorlar.
İKİ DEĞİŞKENİN DEĞERİNİN TAKAS YAPILMASI
Elimizde olan iki değişkenin değerini yer değiştirmek istersek, ne yapmamız
gerekir? Mesela; adeğişkeninde 5 değeri var, b değişkeninde ise 10 değeri var.
Biz tam tersi a değişkeninde 10, b değişkeninde 5 değerinin olmasını istiyoruz.
Bunu atama operatörünü kullanarak nasıl yaparız, şimdi onu görelim.
//Operatorler4.java - 04.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Operatorler4
{
public static void main(String[]
args)
{
int a = 5;
int b = 10;
int c;
c = a; // c de 5 değeri var
a = b; // a da 10 değeri var
b = c; // b de 5 değeri var
System.out.println("a değeri " +
a);
System.out.println("b değeri " +
b);
}
}
Ekran çıktısı:
1
a değeri 10
2
b değeri 5
Görüldüğü gibi a değeri 5 iken 10 oldu. b değeri de 10 iken 5 oldu. Yani
birbirinin değerini değiş tokuş yaptılar. Bunun için c değişkenini kullandık ve
bu değişken geçici olarak değer taşıdı.
Ders 19 - İlişkisel Operatörler
İlişkisel operatörler, veriler arasında karşılaştırma yapmaya yarar. Bunları
şöyle sıralayabiliriz.

< küçüktür

> büyüktür

<= küçük eşittir

>= büyük eşittir

== eşittir

!= eşit değildir
Bu operatörler iki verinin karşılaştırmasını yapar. Dönen
değer boolean türündeki true veya false'dur.
Basit bir örnek verelim.
1
int a = 10;
2
int b = 6;
3
System.out.println(a > b);
Burada a değerimiz b'den büyük olduğu için ekrana true yazar. Eğer aradaki
operatörümüz != olsaydı, bu iki değer birbirinden farklı olduğu için
yine true dönecekti. Bu örnekte dönen true değeri, doğrudan ekrana yazdırıldı.
Ekrana yazdırmak yerine boolean türünde bir değişkene atayıp, buna göre de
işlem yaptırabilirdik.
Bu anlattığımızı örneklersek:
1
//Operatorler.java - 04.04.2014
2
3
public class Operatorler
4
{
5
public static void main(String[]
6
args)
7
{
8
int a = 5, b = 6;
9
10
11
12
13
boolean sonuc = a < b;
System.out.println(sonuc);
}
}
Ekran çıktısı:
1
true
sonuc değişkenine true değeri atanacaktır. Bu şekilde de değişkenleri kontrol
edip, sonucu doğrudan boolean tipindeki değişkene atayabiliriz.
Başka bir örnek verelim:
//Operatorler2.java - 04.04.2014
1
2
public class Operatorler2
3
{
4
public static void main(String[] args)
5
{
6
int x = 10;
7
int y = 16;
8
if (x > y)
9
System.out.println("x y'den
10
büyüktür");
11
if (x < y)
12
System.out.println("x y'den
13
küçüktür");
14
}
15
}
16
Ekran çıktısı:
1
x y'den küçüktür
Bu örnekte de değişkenlerimizin birbirine göre konumları
karşılaştırılmıştır. x değişkeni y'den küçük olduğu için ekrana "x y'den
küçüktür" yazacaktır. Bunu if else yapıları ile sağladık. Bu yapılar ile herhangi
bir operatörü kullanarak işlem yapabiliriz. if else yapısının kullanımından
ileriki derslerimzide bahsedeceğiz.
İlişkisel, yani karşılaştırma operatörlerinin daha fazlasını kullanarak bir örnek
daha yapalım.
//Operatorler3.java - 04.04.2014
1
2
public class Operatorler3
3
{
4
public static void main(String[] args)
5
{
6
int sayi1 = 1;
7
int sayi2 = 2;
8
if(sayi1 == sayi2)
9
System.out.println("Sayılar aynı");
10
if(sayi1 != sayi2)
11
System.out.println("Sayılar farklı");
12
if(sayi1 < sayi2)
13
System.out.println("sayi1 daha küçüktür");
14
if(sayi1 > sayi2)
15
System.out.println("sayi2 daha küçüktür");
16
if(sayi1 >= sayi2)
17
System.out.println("sayi1, sayi2'den büyük ve
18
eşittir");
19
}
20
}
21
22
Ekran çıktısı:
1
Sayılar farklı
2
sayi1 daha küçüktür
Bu son örneğimizde sayi1 ve sayi2'yi karşılaştırdık. Olabilecek çoğu durum
için sonuçları inceledik. Sayıların birbirine olan konumlarına göre ekrana
çıktılarımızı yazdık.
Ders 20 - Aritmetik Operatörler
Aritmetik operatörler, matematiksel işlemler yapmak için kullanılır. Bunları
şöyle sıralayabiliriz:

+ Toplama işlemi yapar.

- Çıkarma işlemi yapar.

* Çarpma işlemi yapar.

/ Bölme işlemi yapar.

% Mod işlemi yapar, işlem sonucunda kalanı verir.

++ Değeri 1 artırır.

-- Değeri 1 azaltır.
TEMEL ARİTMETİK OPERATÖRLER ( +, -, *, / )
Bu operatörler, bildiğimiz 4 işlem yapan operatörlerdir. İlk olarak 4 işlem ile
ilgili örnek yapalım.
//Operatorler.java - 04.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Operatorler
{
public static void main(String[] args)
{
int x = 8;
int y = 5;
System.out.println("Toplama işlemi sonucu: " +
(x+y));
System.out.println("Çıkarma işlemi sonucu: " +
(x-y));
System.out.println("Çarpma işlemi sonucu: " +
(x*y));
System.out.println("Bölme işlemi sonucu: " +
(x/y));
}
}
Ekran çıktısı:
1
Toplama işlemi sonucu: 13
2
Çıkarma işlemi sonucu: 3
3
Çarpma işlemi sonucu: 40
4
Bölme işlemi sonucu: 1
Bölme işleminin sonucunda 1 değeri döner. Bunun sebebi; iki int değerinin
bölümünün yine true tipinde olmasıdır. Eğer bunun küsüratlı olmasını
istiyorsak, iki değerimizden herhangi birini double veya floatyapmamız
gerekirdi.
Bu örnekte sonuçları ekrana yazdırırken, değerleri parantez içerisine aldık.
Bunu yapmazsak hata alırız. Çünkü + operatörü hem değerleri birleştirir hem de
toplama yapar. Yani iki ayrı görevi vardır. Bu görevleri birbirinden ayırt etmek
için parantez kullandık.
MOD OPERATÖRÜ ( % )
Bu operatör, mod işleminden kalanı bize verir. Mod işlemi yapan (%)
operatörüne de bir örnek verelim.
1
2
public class Operatorler2
3
{
4
public static void main(String[] args)
5
{
6
int sayi1 = 40;
7
int sayi2 = 6;
8
System.out.println(sayi1 % sayi2);
9
}
10
}
11
12
13
Ekran çıktısı:
1
4
Görüldüğü gibi % operatörü, iki değeri birbirine bölerek kalanı verir. Bu
operatör farklı amaçlar için de kullanılabilir. Genelde tek ve çift sayıları
bulmada işe yarar.
( - ) OPERATÖRÜ İLE SAYIYI NEGATİF YAPMA
Çıkarma işlemi yapan - operatörü, sayıların negatif olmalarını da sağlar. Pozitif
olan bir değeri, negatif değerine çevirir. Buna bir örnek verelim ve çıktısını
inceleyelim.
1
2
public class Operatorler3
3
{
4
public static void main(String[]
5
args)
6
{
7
int x = 5;
8
x = -x;
9
System.out.println(x+x);
10
}
11
}
12
13
Ekran çıktısı:
1
-10
Değişkenimiz olan x'in başına - operatörünü koyarak negatif olmasını sağladık
ve kendisi ile toplayarak sonucu ekrana yazdırdık.
ARTIRMA ( ++ ) VE AZALTMA ( -- ) OPERATÖRLERİ
Bu operatörler, bir sayının değerini 1 artırır veya 1 azaltır. Fakat değişkenlerin
değerini artıran veya azaltan ++ ve -- operatörlerinde bir istisna vardır. Bu
operatörler, değişkenin başına veya sonuna gelebilir. Değişkenden önce ve
sonra geldiği zaman ne gibi farklılıklar olduğunu bir örnek üzerinde
gözlemleyelim.
1
//Operatorler4.java - 04.04.2014
2
3
public class Operatorler4
4
{
5
public static void main(String[] args)
6
{
7
int sayi1 = 10;
8
int a, b;
9
a = sayi1++;
10
b = sayi1;
11
System.out.println("Sona yazılırsa: " + a);
12
System.out.println("Sayının yeni değeri: "
13
+ b);
14
15
16
}
}
Ekran çıktısı:
1
Sona yazılırsa: 10
2
Sayının yeni değeri: 11
Görüldüğü gibi a değerinin 11 olmasını bekliyorduk, çünkü artırma
operatörünü kullandık. Fakat buradaki istisna şudur: Eğer ++ operatörünü sona
yazarsak, önce sayi1'i a'ya atar. Böylece a değişkenimiz 10 olur. Daha
sonra artırma işlemini yapar. Artırma işlemini yaptıktan
sonra sayi1 değişkenimiz 11 olur. Fakat bu 11 değeri, alt satırlarda kullanılır,
işlem yapılan satıra yansımaz. Bir alt satırda bu değer 11 olmuştur artık. Şimdi
daha karmaşık bir örnek verelim ve çıktısını görelim.
//Operatorler5.java - 04.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Operatorler5
{
public static void main(String[]
args)
{
int sayi1 = 20;
int a, b, c, d, e, f;
a = ++sayi1;
b = sayi1--;
c = --sayi1;
d = ++sayi1;
e = sayi1++;
f = sayi1;
System.out.println("A değeri " +
a);
System.out.println("B değeri " +
b);
System.out.println("C değeri " +
c);
System.out.println("D değeri " +
d);
System.out.println("E değeri " +
e);
System.out.println("F değeri " +
f);
}
}
Ekran çıktısı:
1
A değeri 21
2
B değeri 21
3
C değeri 19
4
D değeri 20
5
E değeri 20
6
F değeri 21
Kod parçacığımızı baştan inceleyelim...
1.
İlk olarak sayi1'i önce artırdık. Daha sonra a'ya atadık.
Sayımız 21 oldu.
2.
Alttaki satırda 21'i önce b'ye atadık. Daha sonra 1 azaltarak 20 yaptık.
Sayımız 20 oldu.
3.
Bir alt satırda 20'yi azalttık ve c'ye atadık. Sayımız 19 oldu.
4.
Sonra 19'u artırdık ve d'ye atadık. Sayımız tekrar 20 oldu.
5.
Daha sonra 20'yi önce e'ye atadık. Daha sonra 1 artırdık.
Sayımız 21 oldu. Bu 21 sayısı, alt satırda kullanılabilecek.
6.
Son olarak da bu değeri f'ye atayarak bütün değerleri ekrana yazdırdık.
Ders 21 - Mantıksal Operatörler
Dersimizin başında operatörlerden bahsederken login örneğini vermiştik. Orada
kullanılan karşılaştırmalar, mantıksal operatörler ile yapılmaktadır. Lojik
devrelerde kullanılan kapı işlemleri de bu operatörler ile yapılır. Bu operatörler
ihtiyaca göre farklı amaçlar için de kullanılabilir. Login işleminde
hemkullanıcı adının hem de şifrenin uyuşması gerekir. Bunu mantıksal
operatörler ile yapabiliriz. Bunun dışında çok farklı kullanım alanları vardır.
Şimdi bu operatörleri inceleyelim.

& Mantıksal VE(AND) işlemi yapar. Verilen değerleri AND işlemine
tabi tutar.

| Mantıksal VEYA(OR) işlemi yapar.

&& Koşullu VE işlemi yapar. Karşılaştırılan iki değerden her ikisi
de true olduğu sürece, true döndürür.

|| Koşullu VEYA işlemi yapar. Karşılaştırılan iki değerden en az
biri true olduğu sürece, true döndürür.

! Mantıksal NOT(DEĞİL) işlemi yapar. Verilen boolean tipindeki
verinin tersini verir. true ise false, falseise true.

^ Mantıksal XOR işlemi yapar. Verilen iki değeri XOR işlemine tabi
tutar.
Bir örnek verelim:
//Operatorler.java - 04.04.2014
1
2
public class Operatorler
3
{
4
public static void main(String[] args)
5
{
6
String kullanici_adi = "elektroarge";
7
int sifre = 1234;
8
if (kullanici_adi == "elektroarge" && sifre ==
9
1234);
10
System.out.println("Giriş Başarılı");
11
}
12
}
13
14
Ekran çıktısı:
1
Giriş Başarılı
Bu örnekte kullanıcı_adı ve şifrenin her ikisinin de uyuştuğu
zaman login işlemi yapılıyor. Bunu sağlamak için mantıksal operatörlerden
olan && operatörü kullanılıyor. Bu tip örnekleri çoğaltabiliriz. Yalnızca
herhangi birinin doğru olduğu zaman bir işlem yapmak
istiyorsak, || operatörünü kullanmamız gerekir.
Şimdi geniş kapsamlı bir örnek verelim ve tüm mantıksal operatörleri
kullanalım.
//Operatorler2.java - 04.04.2014
1
2
public class Operatorler2
3
{
4
public static void main(String[] args)
5
{
6
boolean x = false;
7
boolean y = true;
8
System.out.println("x & y = " + (x & y));
9
System.out.println("x | y = " + (x | y));
10
System.out.println("x && y = " + (x && y));
11
System.out.println("x || y = " + (x || y));
12
System.out.println("x ^ y = " + (x ^ y));
13
System.out.println("!x = " + (!x));
14
System.out.println("(x & y) || (x ^ y) = " + ((x & y) || (x
15
^ y)));
16
}
17
}
18
19
Ekran çıktısı:
1
x & y = false
2
x | y = true
3
x && y = false
4
x || y = true
5
x ^ y = true
6
!x = true
7
(x & y) || (x ^ y) = true
Bu örnekte x yerine false, y yerine true yazdığımız zaman sonuçları rahatlıkla
bulabiliriz. Bunun için AND,OR ve XOR gibi işlemlerin doğruluk tablolarını
bilmemiz gerekiyor.
X
Y
false
false
false
true
true
false
true
true
X&Y
false
false
false
true
X|Z
false
true
true
true
X xor Y
false
true
true
false
X!
true
true
false
false
Y!
true
false
true
false
Ders 22 - Bitsel Operatörler
Programlamada pek fazla kullanılmayan bitsel operatörler, bitleri kaydırmak,
tersini almak gibi işlemler için kullanılır. Bu bitsel operatörlerin temel
olanlarını gösterelim.

~ Bütün bitlerin tersini alır. 1 ise 0 yapar, 0 ise 1 yapar.

& Bitsel olarak VE işlemi yapar.

| Bitsel olarak VEYA işlemi yapar.

^ Bitsel olarak XOR işlemi yapar.

>> Bitsel olarak sayısı istenilen değer kadar sağa kaydırır.

<< Bitsel olarak sayısı istenilen değer kadar sola kaydırır.
Mesela; 3 sayısını düşünelim. Bu sayı 0011'e karşılık gelir. Diğer bir sayı
olarak da 14 sayısını düşünelim. Bu da 1110'a karşılık gelir.
Biz 3 ile 14 sayısını AND işlemine tabi tuttuğumuzda, bu sayılara karşılık gelen
bitler tek tek AND işlemine tabi tutulur.
Yani verilen bir sayı, doğrudan işleme tabi tutulmaz. Bu verilen
sayının binary karşılığı işleme tabi tutulur.
TEMEL BİTSEL OPERATÖRLER ( ~, &, |, ^ )
Konuya giriş yaparken bu operatörlerin ne anlama geldiğini söylemiştik. Şimdi
örnekler üzerinde gösterelim. İşleme tabi tutacağımız ilk sayılar 3 ve 14 olsun.
Bunun binary karşılıklarını bilmemiz gerekir.
AND İşlemi:
Istisnalar:
!
1. sayı = 0011 (3)
2. sayı = 1110 (14)
Sonuç = 0010 (2) - (&-AND İşlemi)
Bunun örneğini verirsek;
1
//Operatorler.java - 04.04.2014
2
3
4
5
6
7
8
9
10
11
public class Operatorler
{
public static void main(String[]
args)
{
System.out.println(3 & 14);
}
}
Ekran çıktısı:
1
2
Bu örnekte 3 ile 14 sayısını & operatörü ile AND işlemine tabi tuttuk ve tüm
bitleri, birbiri ile işlemi soktuktan sonra 2 sayısını (0010) elde ettik.
Bu bitsel operatörlerden XOR işlemi yapan ^ operatörüne örnek verelim.
AND İşlemi:
Istisnalar:
!
1. sayı = 0011 (3)
2. sayı = 1110 (14)
Sonuç = 0010 (2) - (&-AND İşlemi)
Örnek verirsek:
//Operatorler2.java - 04.04.2014
1
2
public class Operatorler2
3
{
4
public static void main(String[]
5
args)
6
{
7
System.out.println(3^14);
8
}
9
}
10
11
XOR işleminde işleme giren bitler farklı ise sonuç 1 oluyordu, ise sonuç 0
oluyordu. Verdiğimiz 3 ve 14sayılarının
aslında binary karşılıklarını XOR işlemine tabi tuttu ve çıkan 1101 sayısını da
10'luk tabana çevirdi ve 13 sayısını verdi.
~ İle Bitlerin Tersini Alma:
1
Sayı = 1101 (13)
2
Sonuç = 0010 (2)
Bitlerin tersini alan ~ operatörüne de bir örnek verelim.
3 sayısı, 0011 bitlerine karşılık gelir. Bunu ~ ile işleme sokalım.
//Operatorler3.java - 04.04.2014
1
2
public class Operatorler3
3
{
4
public static void main(String[]
5
args)
6
{
7
System.out.println(~3);
8
}
9
}
10
11
Ekran çıktısı:
1
-4
3 olan 0011 sayımızın bütün bitlerini terse çevirirsek 1100 olur. En baştaki bit
işaret biti olduğu için sonucumuz negatif oldu. Kalan 100 bitleri de 4'e karşılık
gelir.
KAYDIRMA OPERATÖRLERİ ( >>, << )
Sağa ve sola kaydırma konusunu örnek üzerinde anlatalım. Yapacağımız işlem
9 sayısını 2 defa sola kaydırmak (9 << 2) ve 9 sayısını 2 defa sağa kaydırmak (9
>> 2) olsun.
1
36
2
2
9 sayısı 1001'e karşılık gelir. Bu sayıyı 2 bit sola kaydırdığımızda bütün bitler 2
kere sola kaydırılır ve en sağdan da 2 tane 0 gelir. Yeni sayımız 100100 olur.
Bu da 36'ya karşılık gelir.
9 sayısı 1001'e karşılık gelir. Bu sayısı 2 bit sağa kaydırdığımızda en sağdaki 2
bit kaybolur ve kalan bitler 2 basamak sağa kayar. Yeni sayımız 0010 olur ve
bu da 2'ye karşılık gelir.
Bitsel operatörlere son bir örnek vererek konumuzu kapatalım.
//Operatorler4.java - 04.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Operatorler4
{
public static void main(String[] args)
{
byte x = 6;
System.out.println("Sayımız : " + x);
System.out.println("~x sonucu: " + ~x);
System.out.println("x&3 sonucu: " +
(x&3));
System.out.println("x<<2 sonucu: " +
(x<<2));
System.out.println("x>>2 sonucu: " +
(x>>2));
}
}
Ekran çıktısı:
1
Sayımız : 6
2
~x sonucu: -7
3
x&3 sonucu: 2
4
x<<2 sonucu: 24
5
x>>2 sonucu: 1
Ders 23 - Tip Karşılaştırma Operatörü
Tip karşılaştırma operatörleri, genelde bir nesnenin, bir sınıfın örneği olup
olmadığını belirlemek için kullanılır. Sonuç olarak true veya false döndürür.
Basit bir örnek vererek olayı açıklayalım.
//Operatorler.java - 04.04.2014
1
2
class Sinif1
3
{
4
}
5
class Sinif2
6
{
7
}
8
public class Operatorler
9
{
10
public static void main(String[] args)
11
{
12
Sinif1 s1 = new Sinif1();
13
Sinif2 s2 = new Sinif2();
14
15
if(s2 instanceof Sinif2)
16
System.out.println("s2, Sinif2 nin bir örneğidir");
17
else
18
System.out.println("s2, Sinif2 nin bir örneği
19
değildir");
20
}
21
}
22
23
Ekran çıktısı:
1
s2, Sinif2 nin bir örneğidir
Burada Sinif1 ve Sinif2'den birer nesne oluşturduk. Bunları if else yapısı
içerisinde karşılaştırdık. s2nesnesi, Sinif2'den türetildiyse ekrana bilgi mesajı
yazılmasını sağladık.
Ders 24 - Operatör Önceliği
Matematik işlemlerinde olduğu gibi yazılım dillerinde de işlem önceliği
vardır. Çarpma ve bölme işlemi,toplama ve çıkarmaya göre daha
önceliklidir. Aşağıdaki kod, çıktı olarak 18 verecektir.
//Operatorler.java - 04.04.2014
1
2
public class Operatorler
3
{
4
public static void main(String[]
5
args)
6
{
7
System.out.println(7 + 4 * 8 / 2 8
5);
9
}
10
}
11
Ekran çıktısı:
1
18
Öncelikler, bu şekilde olabileceği gibi parantezler ile de yapılabilir.
Parantezler ile öncelik yaparsak; sağdan ve soldan öncelik olarak 2 şekilde
incelememiz gerekir. Buna bir örnek verelim.
//Operatorler2.java - 04.04.2014
1
2
public class Operatorler2
3
{
4
public static void main(String[] args)
5
{
6
System.out.println(4 + (5 + (2 * 6))); // sağdan
7
öncelikli
8
System.out.println(((3 / 1) * 4) - 6); // soldan
9
öncelikli
10
}
11
}
12
Ekan çıktısı:
1
21
2
6
Parantezler ile işlem yapmayı biliyoruz. Programlama dillerinde de bu şekilde
bir yapıdır. Sağdan öncelikli işlemlerde önce en sağdaki parantezdeki işlem
yapılır ve sola doğru gidilir. Soldan öncelikli işlemlerde ise bunun tersi
geçerlidir.
Şimdi operatörlerin öncelik sırasını, yüksekten düşüğe doğru yazalım.
1.
Parantezler, dizi elemanına erişme( [] )
2.
Sona yazılan ++ ve -- operatörleri
3.
Başa yazılan ++ ve -- operatörleri
4.
new ile nesne oluşturma
5.
Çarpma, bölme, mod alma (*, /, %)
6.
Toplama ve çıkarma, String toplama (+, -)
7.
Kaydırma operatörleri (<<, >>)
8.
İlişkisel operatörler (<, >, <=, >=)
9.
Mantıksal operatörler (&, |, ^)
Ders 25 - Kontrol Yapıları
Kod yazarken bazı şartlara bağlı olarak, belirlediğimiz bir olayın
gerçekleşmesini isteyebiliriz. Basit bir not sistemi düşünelim. Öğrenci, 50'den
düşük not aldığında dersten geçemesin. Bunu sağlamak için kontrol yapılarını
kullanmamız gerekir. Java'da 3 tür kontrol yapısı vardır. Bunlar; if-else, if-else
if ve switchyapılarıdır. Yapmak istediğimiz işlemlere hangi kontrol yapısı
uygun oluyorsa, onu kullanırız.
IF - ELSE YAPISI
Bir öğrenci not sistemi düşünelim. Öğrencinin ortalaması 85'ten yukarı olursa
AA, 70 ile 85 arası olursa BA gelmiş olsun. Bunun için if - else yapısını
kullanmalıyız. If - else yapısında koşul içerisindeki
ifadeden truedöndüğü(koşul doğru olduğu) sürece if bloğuna girer
ve (a) bloğundaki işlemler yapılır. Eğer koşuldan falsesonucu
dönerse, else kısmına girer ve buradaki (b) bloğu işlenir. Eğer else kısmında bir
işlem yapılmasını istemiyorsak, else kısmını yazmadan sadece if deyimini
kullanabiliriz.
If - else yapısının genel yapısı:
1
if (koşul)
2
{
3
// işlemler (a)
4
}
5
else
6
{
7
// işlemler (b)
8
}
If - else yapısının akış şeması:
Bunu bir örnekle gösterelim:
1
//IfElseYapısı.java - 04.04.2014
2
3
public class IfElseYapısı
4
{
5
public static void main(String[] args)
6
{
7
int not = 88;
8
if (not > 50)
9
System.out.println("Başarılı");
10
else
11
System.out.println("Başarısız");
12
}
13
14
15
}
Ekran çıktısı:
1
Başarılı
Eğer if veya else kısmında yapılacak işlemler tek bir ifade ise, kod bloğunu
süslü parantezler { } içine koymaya gerek yoktur. Ekrana "Başarılı"
yazdırmasının yanında başka bir ifade de yazacak olsaydık, aşağıdaki gibi süslü
parantezler { } içerisine yazmamız gerekecekti.
if (not > 50)
1
{
2
System.out.println("Başarılı");
3
System.out.println("Dersi
4
Geçtiniz");
5
}
Ekran çıktısı:
1
Başarılı
2
Dersi geçtiniz
İlk örneğimizde tek bir ifade olduğu için biz süslü parantezler içerisine
koymadık. İfadeden kastımız, sonuna noktalı virgül getirilen her şeydir.
if içerisinde kullanacağımız değerleri kendimiz vermek yerine, kullanıcıdan da
alabiliriz. Bunu Scannersınıfları ile yapıyoruz. Bu konuyu Scanner
Sınıfları derslerinden sonra, tekrar bu derse bakarsanız faydalı olacaktır.
1
//IfElseYapısı2.java - 04.04.2014
2
3
import java.util.Scanner;
4
5
public class IfElseYapısı2
6
{
7
public static void main(String[] args)
8
{
9
Scanner s = new Scanner(System.in);
10
System.out.println("İlk sayıyı girin: ");
11
int sayi1 = s.nextInt(); // ilk sayı alındı
12
System.out.println("İkinci sayıyı girin: ");
13
14
15
16
17
18
19
20
21
int sayi2 = s.nextInt(); // ikinci sayı alındı
if(sayi1 > sayi2)
System.out.println(sayi1 + ", " + sayi2 + "'den
büyüktür.");
else
System.out.println(sayi1 + ", " + sayi2 + "'den
küçüktür.");
}
}
Ekran çıktısı:
1
İlk sayıyı girin:
2
4
3
İkinci sayıyı girin:
4
6
5
4, 6'den küçüktür.
Bu örnekte kullanıcıdan iki sayı aldık ve karşılaştırdık. Durumlarına göre
ekrana bilgilendirme mesajı yazdırdık. Yalnız bu sayıların eşit olmadığını
varsayıyoruz. Çünkü onun kontrolü için bir sonraki konu olan if - else
if kontrolünü kullanmaya ihtiyacımız var.
IF - ELSE IF YAPISI
If else dersinde anlattığımız ilk örnekte 2 tane şartımız vardı. Fakat biz geçti
kaldı türünden değil de doğrudan harf notunu (AA - BB) göstermek istiyoruz.
Bunun için 2 koşul (if ve else) yetmeyecektir. Ortalama 8 tür harf notu
olduğunu düşünürsek, 8 tane şartımız olur. Birden fazla koşul kullanmamız
gerektiği için if - else if yapısı kullanılmalıdır. Buna bir örnek verelim:
1
//IfElseIfYapısı.java - 04.04.2014
2
3
public class IfElseIfYapısı
4
{
5
public static void main(String[] args)
6
{
7
int not = 76;
8
if (not > 85)
9
System.out.println("Harf Notu
10
AA");
11
12
13
14
15
16
17
else if (not < 85 && not >= 70)
System.out.println("Harf Notu
BA");
else if (not < 70 && not >= 60)
System.out.println("Harf Notu
BB");
}
}
Ekran çıktısı:
1
Harf Notu BA
Bu örnekte if - else yapısını kullansaydık, yalnızca 2 şartı kontrol edebilirdik.
2'den fazla ihtimal olduğu çinif - else if yapısını kullanmalıyız.
Istisnalar:
!
Şimdiye kadar verdiğimiz örneklerde if koşulunun içerisine büyükse,
küçükse gibi şartlar koyduk. Bunların haricinde eşitse (==), büyük
eşitse (>=), eşit değilse (!=) gibi şartlar da koyabiliriz. Bir önceki
örnekte olduğu gibi koşul içerisinde birden fazla şartımız varsa,
mantıksal operatörler de (&&, ||) kullanılabilir.
İÇ İÇE IF YAPILARI
IF yapılarını iç içe de kullanabiliriz. Koşula bağlı olarak bir bloğa
dallandığımızda, o blok içerisinde tekrar bir kontrol daha yapmak isteyebiliriz.
Bunu bir örnek üzerinde gösterelim:
1
//IfElseYapısı3.java - 04.04.2014
2
3
public class IfElseYapısı3
4
{
5
public static void main(String[] args)
6
{
7
int hiz = 110;
8
if (hiz > 90)
9
{
10
System.out.println("Radara
11
girdiniz");
12
if(hiz >= 90 && hiz < 120)
13
14
15
16
17
18
19
20
21
System.out.println("Cezanız 200
TL");
else if (hiz >= 120)
System.out.println("Cezanız 400
TL");
else
System.out.println("Hızınız
Normal");
}
}
}
Ekran çıktısı:
1
Radara girdiniz
2
Cezanız 200 TL
Yukarıdaki örnekte sürücünün hızı 90'dan az ise "Hızınız Normal" yazısını
gösteriyor. Eğer hızı 90'a eşit ve büyükse "Radara Giriniz" yazısını gösteriyor
ve hızının büyüklüğüne göre cezası belirtiliyor. Son olarak if - else if yapısına
bir örnek daha verelim:
1
//IfElseYapısı4.java - 04.04.2014
2
3
public class IfElseYapısı4
4
{
5
public static void main(String[] args)
6
{
7
int dogru = 75, yanlis = 25;
8
double net = dogru - (float)yanlis /
9
4;
10
if(net >= 85)
11
System.out.println("Çok
12
Başarılı");
13
else if(net >= 70 && net < 85)
14
System.out.println("Orta
15
Seviye");
16
else if(net >= 55 && net < 70)
17
System.out.println("İdare
18
Eder");
19
else
20
System.out.println("Kötü");
21
System.out.println("Netiniz = " +
net);
}
}
Ekran çıktısı:
1
İdare Eder
2
Netiniz = 68.75
Burada program başlangıcında, 4 yanlışın 1 doğruyu götürdüğünü düşünerek,
net hesaplaması yaptık. Burada yanlışı hesaplarken float'a cast ettik. Bunun
sebebi, yanlışların küsüratlı sonuçlar üretebilmesidir. Bunu yapmasaydık bütün
netleri tam sayı olarak hesaplayacaktı.
SWITCH YAPISI
Switch kontrolü, if - else yapısının bir alternatifi olarak oluşturulmuştur. Uzun
uzun else if şartları koymak yerine, bunu tek bir switch kontrolü ile yapabiliriz.
Fakat bir önceki örneğimizde switch yapısı kullanamayız.
Switch kontrolleri belirli bir aralık değil de doğrudan değer kontrolü yapar. O
yüzden her if - else yerineswitch yapıları kullanamayız. Mesela; günlerden
pazartesi ise şunu yap, Salı ise bunu yap diyebiliriz. Eğer bunu if - else if ile
yapsaydık, uzun uzadıya kod yazmamız gerekirdi.
switch(i)
1
{
2
case a: // eğer i değeri a'ya eşit ise, bu blok işlenir.
3
break;
4
case b: // eğer i değeri b'ye eşit ise, bu blok işlenir.
5
break;
6
default: // eğer i değeri hiçbirine eşit değil ise, bu blok
7
işlenir.
8
break;
9
}
Switch Yapısının Akış Şeması:
Switch yapılarına bir örnek vererek açıklayalım:
//SwitchYapısı.java - 04.04.2014
1
2
public class SwitchYapısı
3
{
4
public static void main(String[] args)
5
{
6
int i = 2;
7
switch(i)
8
{
9
case 1:
10
System.out.println("Sayımız 1'dir");
11
break;
12
case 2: System.out.println("Sayımız 2'dir");
13
break;
14
case 3: System.out.println("Sayımız 3'tür");
15
break;
16
default: System.out.println("Sayımız 1, 2 veya 3
17
değildir");
18
break;
19
}
20
}
21
}
22
23
Ekran çıktısı:
1
Sayımız 2'dir
Bu yapıda switch içerisine kontrol edeceğimiz değişkeni yazarız. case ile de
bunları karşılaştırırız. Switch içerisindeki değişkenin değeri ile case'deki
değişken eşleştiği zaman, eşleşen case bloğuna girilir. Her caseifadesinden
sonra da break; koymamız gerekir. Eğer koymazsak bir sonraki case ifadesine
de girer veSayımız 3'tür ifadesini de ekrana yazdırır. Hiçbir case ifadesinden
sonra break koymazsak bütün caseifadelerine girer ve her çıktıyı ekrana
yazdırır.
Break ifadesine daha sonra tekrar deneyeceğiz. En sona
yazdığımız default: ise hiçbir case ifadesine girilmediğinde
çalıştırılır. Default ifadesinin yazılma zorunluluğu yoktur, isteğe bağlıdır.
Break; ifadesini yazmadığımızda meydana gelebilecek duruma bir örnek
verelim:
//SwitchOrnekler.java - 04.04.2014
1
2
public class SwitchOrnekler
3
{
4
public static void main(String[] args)
5
{
6
byte x = 10;
7
switch (x)
8
{
9
case 10: System.out.println("Sayımız 10
10
dur");
11
case 20: System.out.println("Sayımız 20
12
dir");
13
break;
14
case 30: System.out.println("Sayımız 30
15
dur");
16
break;
17
default: System.out.println("Geçersiz");
18
break;
19
}
20
}
21
}
Ekran çıktısı:
1
Sayımız 10 dur
2
Sayımız 20 dir
Görüldüğü gibi ilk case ifadesinde break; koymadığımız için hem kendi
bloğundakini hem de bir sonrakicase bloğundaki ifadeleri ekrana yazdırdı.
Her case ifadesinin kendine göre işlem yapması için caseifadelerinden
sonra break; koyulur. break; ifadesini ileriki derslerimizde detaylı olarak
işleyeceğiz.
Ayrıca case ifadelerinde ne kadar komut olursa olsun, komutları süslü
parantezler içerisine almak gerekmez.
Istisnalar:
!
switch içerisinde sadece int tipinde değil; short, byte ve char tipinde
değişkenler de yazılabilir. Java SE 7 ile gelen bir özellik
ile switch içerisinde String değişkenler de kontrol edilebilmektedir.
switch yapısında sadece bir case değeri ile karşılaştırma yapılmayabilir. Yani
sayımız hem 1 hem 2 iken, şunları yap diyebiliriz. Bu anlattığımıza bir örnek
verelim:
1
//SwitchOrnekler2.java - 04.04.2014
2
3
public class SwitchOrnekler2
4
{
5
public static void main(String[] args)
6
{
7
int sayi = 2;
8
switch(sayi)
9
{
10
case 1: case 3: case 5: case 7:
11
case 9:
12
System.out.println("Sayı
13
tektir");
14
break;
15
case 2: case 4: case 6: case 8:
16
System.out.println("Sayı
17
çiftir");
18
19
20
break;
}
}
}
Ekran çıktısı:
1
Sayı çifttir
Yukarıdaki örnekte birden fazla case ifadesi beraber kullanılmıştır. İleriki
derslerimizde de switch yapısını kullanarak çok sayıda örnek yapacağız.
Istisnalar:
!
switch kontrollerinin içerisinde if else yapıları kullanıldığı gibi if
else yapılarının içerisinde de switch yapılarını kullanabiliriz.
Ders 26 - Döngüler
Oluşturacağımız programlarda bazı olayların tekrarlanmasını isteyebiliriz.
Tekrarlanan bu olaylar ile işlemlerimizi daha kolay bir şekilde yaparız. Bu
döngülerde belirtilen koşul doğru olduğu sürece döngü içerisidneki komutlar
çalışır ve komut dışına çıkıldığında ise döngü biter. Döngüden çıkıldığında ise
döngü bitiminden itibaren program çalışmaya devam eder.
Java'da while, do - while ve for olmak üzere 3 tip döngü vardır.
WHILE DÖNGÜSÜ
while döngüsünde, tekrar sayısı belli değildir. Döngü içerisinde
oluşturacağımız şartlara göre döngü devam eder veya sonlanır. Belirtilen
koşulda true değeri döndüğü sürece döngü çalışır ve false değeri dönüp
döngüden çıkınca program, döngünün bittiği yerden çalışmasına devam eder.
İken anlamına gelen bu döngü türünde, koşul ... iken, şunları şunları yap
diyebiliriz..
Genel Kullanım Şekli:
1
2
3
4
while(koşul)
{
// işlemler
}
While Döngüsünün Akış Şeması:
Bunu bir örnekle açıklayalım:
//WhileDongusu.java - 04.04.2014
1
2
public class WhileDongusu
3
{
4
public static void main(String[] args)
5
{
6
int sayi = 5;
7
while (sayi > 0)
8
{
9
System.out.println("Sayı pozitif, değeri: " +
10
sayi);
11
sayi--;
12
}
13
}
14
}
15
16
Sayımız 5'ten büyük olduğu sürece döngümüz çalışır. Döngü içerisinde
ise, sayi değerimiz 1 azaltılır. Değer azaltılıp while döngüsünün tekrar başına
gelinir ve bu, sayımız 0 olana kadar devam eder. Değişkenimiz 0 olduğunda
ise, while döngüsündeki koşula uymadığı için artık döngüye girilmez.
Ekran çıktısı:
1
Sayı pozitif, değeri: 5
2
Sayı pozitif, değeri: 4
3
Sayı pozitif, değeri: 3
4
Sayı pozitif, değeri: 2
5
Sayı pozitif, değeri: 1
Bu döngüde, değişkenimizin artış veya azalış miktarı döngü içerisinde
belirtilir. while döngüsünde koşul içerisine sadece int değil, boolean türünde
değişkenler de verebiliriz. Eğer döngümüzdeki koşul, while(true)olursa sonsuz
döngüye girilir ve eğer break; ile döngüden çıkmazsak, sonsuza
kadar while içerisindeki blok işlenir. Örnek üzerinde inceleyelim:
//WhileDongusu2.java - 04.04.2014
1
2
public class WhileDongusu2
3
{
4
public static void main(String[]
5
args)
6
{
7
while(true)
8
{
9
System.out.println("Döngü");
10
System.out.println("Döngü");
11
System.out.println("Döngü");
12
break;
13
}
14
}
15
}
16
17
Ekran çıktısı:
1
Döngü
2
Döngü
3
Döngü
while(true) dediğimizde sonsuz döngüye girilir. break; ile de istediğimiz yerde
döngüyü sonlandırabiliriz.
Bir başka örnek yapalım:
//WhileDongusu3.java - 04.04.2014
1
2
public class WhileDongusu3
3
{
4
public static void main(String[] args)
5
{
6
int i = 10, j = 0, k = 0;
7
while(i > j)
8
{
9
System.out.println("i, j'den büyük");
10
i -= 2;
11
j += 2;
12
k++;
13
}
14
System.out.println("Artık büyük değil");
15
System.out.println("Bu döngü " + k + " kere
16
döndü");
17
}
18
}
19
20
Ekran çıktısı:
1
i, j'den büyük
2
i, j'den büyük
3
i, j'den büyük
4
Artık büyük değil
5
Bu döngü 3 kere döndü
Bu döngü i değeri j'den büyük olduğu sürece dönecektir. Döngü içerisinde,
dönüş sayısını tutan kdeğerini her seferinde 1 artırdık. Aynı anda i değerini 2
artırıp j değerini de 2 azalttık. Bu değerler her döngüde birbirine yaklaşacaklar
ve i değeri j'den küçük olduğu ilk anda döngüden çıkılacak ve döngü dışından
çalışmaya devam edilecektir. Daha sonra da döngü dışındaki iki yazımız ekrana
yazılacaktır.
DO - WHILE DÖNGÜSÜ
Bu döngünün while döngüsünden tek farkı, döngüye girildikten sonra koşula
bakıldığı için koşul yanlış olsa bile döngüye en az bir defalığına girilir.
Genel Kullanım Şekli:
1
do
2
{
3
// işlemler
4
} while(koşul);
Do - While Döngüsünün Akış Şeması:
do - while döngüsüne basit bir örnek verelim:
//DoWhileDongusu.java - 04.04.2014
1
2
public class DoWhileDongusu
3
{
4
public static void main(String[] args)
5
{
6
int sayi = 1;
7
do
8
{
9
System.out.println("Sayı değişkeni: " +
10
sayi);
11
} while(sayi < 0);
12
}
13
}
14
15
Ektan çıktısı:
1
Sayı değişkeni: 1
Görüldüğü gibi sayımız 0'dan küçük değil, fakat döngüye bir defalığına girildi.
Çünkü do fonksiyonu, whilekoşulundan daha önce geliyor.
Bunu while döngüsü ile yapsaydık, döngüye hiç girilmeyecekti. Bu döngü
tipini, koşul yanlış olsa bile bir kere döngüye girilmesini istediğimiz yerlerde
kullanırız.
do - while döngüsüne bir örnek daha verelim:
//DoWhileDongusu2.java - 04.04.2014
1
2
public class DoWhileDongusu2
3
{
4
public static void main(String[] args)
5
{
6
int x = 100, y = 40, i = 0;
7
do
8
{
9
i++;
10
x -= 10;
11
y += 10;
12
} while (x > y);
13
System.out.println("Döngü " + i + " kere
14
döndü");
15
}
16
}
17
18
Ekran çıktısı:
1
Döngü 3 kere döndü
Döngümüzde her seferinde x'in değerini 10 azaltıp y'nin değerini de 10
artırıyoruz. Bu döngü x, y'den küçük olana kadar devam ediyor. Yani x, y'den
büyük olduğu sürece devam eder. Her seferinde de ideğişkenimizi artırarak
döngü sonunda, döngünün kaç defa başa döndüğünü hesaplıyoruz.
FOR DÖNGÜSÜ
Bu döngü türünde bir aralık belirtilir ve bu aralık boyunca döngü çalışır.
Genel Kullanım Şekli:
for (başlangıç değeri; koşul; artım
1
miktarı)
2
{
3
// işlemler
4
}
Döngü içerisindeki şartlar sağlandığı sürece döngü devam eder.
İlk olarak değişkenimize başlangıç değeri verilir. Daha sonra
ifadede koşul belirtilir, koşul doğru olduğu sürece döngü çalışır ve koşul sona
erdiğinde döngüden çıkılır. En sonda ise değişkenimizin artım miktarıverilir.
Bu döngü türünde, while döngüsündeki gibi değişkenin değerinin blok
içerisinde değiştirilmesi gerekmez. Başlangıç değeri, artım miktarı ve koşul
toplu olarak ilk satırda verilir. İlk satırda belirtilen değişkenin her değeri için
komutlar 1 kez çalıştırılır. Bu döngü tipi, genelde belirli bir değere kadar olan
sayıların toplanması, çarpılması ve olayların belirli sayıda tekrar etmesi için
kullanılır.
İlk olarak basit bir örnek ile başlayalım:
//ForDongusu.java - 04.04.2014
1
2
public class ForDongusu
3
{
4
public static void main(String[] args)
5
{
6
for (int i = 1 ; i <= 10 ; i += 2)
7
{
8
System.out.print(i + " "); // sayı aralarında boşluk
9
bırakır
10
}
11
}
12
}
13
14
Ekran çıktısı:
1
13579
Bu döngüde i değişkenimiz 1'den 10'a kadar, 2 şer 2 şer artacaktır. Bu örnekte
değerlerimizi println ile alt alta yazmak yerine arada boşluk bırakarak yan yana
yazdık.
Istisnalar:
!
Burada değişkenimiz for içerisinde tanımlanmak yerine döngünün üst
satırında int i; diyerek de tanımlanabilirdi. O
zaman for içerisine int i; değil de sadece i yazmak yeterli olacaktı.
Şimdi ise for döngüsüne daha gelişmiş bir örnek verelim. Bu örnekte ise 1'den
50'ye kadar olan sayılar içerisinden, 7'ye tam bölünen sayıları ekrana yazdırsın.
1
//ForDongusu2.java - 04.04.2014
2
3
public class ForDongusu2
4
5
6
7
8
9
10
11
12
13
14
15
{
public static void main(String[] args)
{
for (int i = 1 ; i <= 50 ; i ++)
{
if(i % 7 == 0)
System.out.println(i + " Sayısı 7'ye Tam
Bölünür");
}
}
}
Ekran çıktısı:
1
7 Sayısı 7'ye Tam Bölünür
2
14 Sayısı 7'ye Tam Bölünür
3
21 Sayısı 7'ye Tam Bölünür
4
28 Sayısı 7'ye Tam Bölünür
5
35 Sayısı 7'ye Tam Bölünür
6
42 Sayısı 7'ye Tam Bölünür
7
49 Sayısı 7'ye Tam Bölünür
Istisnalar:
!
for içerisinde belirttiğimiz başlangıç değeri, koşul ve artış miktarının
yazılma zorunluluğu yoktur. Yalnızca birini yazabilir veya hiçbirini
yazmayabiliriz. Eğer hiçbirini yazmazsak, sonsuz döngüye girer. Eğer
koşulumuzu yazmazsak da döngümüz sonsuz döngüye girer.
Örnek:
1
for (int i = 0 ; ; i++)
2
for ( ; ; )
for döngüsünde artımı yapılacak olan değişkenimiz birden fazla da olabilir. Bir
değişkenimiz artarken diğer değişkenimiz azalabilir veya senkron olarak
çalışabilir, her ikisi de artabilir. Bu değişkenlerin sayısını artırabiliriz. Fakat
değişkenlerin arasına virgül koyulur. Şimdi bu özelliği kullanarak bir örnek
verelim:
1
//ForDongusu3.java - 04.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ForDongusu3
{
public static void main(String[] args)
{
int i, j;
System.out.println("Döngü başladı");
for(i = 0 , j = 10 ; i < j ; i++ , j--)
{
System.out.println(i + " değeri " + j + " den
küçüktür");
}
System.out.println("Döngü sona erdi");
}
}
Ekran çıktısı:
1
Döngü başladı
2
0 değeri 10 den küçüktür
3
1 değeri 9 den küçüktür
4
2 değeri 8 den küçüktür
5
3 değeri 7 den küçüktür
6
4 değeri 6 den küçüktür
7
Döngü sona erdi
Bu döngü, i değeri j değerinden küçük olana kadar devam eder ve her
döngüde i değerinin j değerinden küçük olduğu ekrana yazdırılır.
Burada i değeri j'den büyük veya eşit olduğu anda döngüden çıkılır.
for döngüsünde dikkat ettiyseniz, değişken olarak hep int kullandık. Bunlar
çoğaltılabilir. Örnek olarak değişkenimizi char tipinde kullanalım ve bir örnek
verelim:
1
//ForDongusu4.java - 04.04.2014
2
3
public class ForDongusu4
4
{
5
public static void main(String[] args)
6
{
7
int i = 1;
8
for (char x = 'a' ; x <= 'e' ; x++)
9
{
10
11
12
13
14
15
16
System.out.println("Alfabenin " + i + ". harfi = "
+ x);
i++;
}
}
}
Ekran çıktısı:
1
Alfabenin 1. harfi = a
2
Alfabenin 2. harfi = b
3
Alfabenin 3. harfi = c
4
Alfabenin 4. harfi = d
5
Alfabenin 5. harfi = e
Örnekte görüldüğü gibi x değişkenimizin tipi char'dır.
GELİŞMİŞ FOR DÖNGÜSÜ
for döngüsünde parantezler içerisine yazdığımız artım miktarı, başlangıç değeri
gibi ifadeleri yazmak yerine daha kısa bir şekilde bu döngüyü oluşturabiliriz.
Diğer dillerde bu yöntemin adı, foreach döngüleridir. Java'da bu
döngüye foreach döngüsü denmez, fakat biz akılda kalması
için foreach döngüsü diyelim. Bu döngü, for döngüsünün gelişmiş halidir.
Aynı işi daha pratik şekilde yapar.
Bu döngü türü, Java 5.0 ile gelen enhanced for loop dediğimiz gelişmiş
bir for döngüsüdür.
Bir dizinin içerisindeki elemanları listelediğimizi düşünelim. Bunu for döngüsü
ile yapmak isteseydik; başlangıç olarak dizinin ilk indisini, bitiş değerini ve
artış miktarını vererek dizinin her elemanını ekrana yazmamız gerekirdi. Bunun
daha kolay bir yolu olan foreach dediğimiz döngüler ile bu işlemi daha az kod
ile yapabiliriz. Bu örnekte, konunun anlaşılması açısından dizileri de kullanmak
zorundayız. Dizileri ileriki derslerimizde anlatacağız.
1
//ForeachDongusu.java - 04.04.2014
2
3
public class ForeachDongusu
4
{
5
6
7
8
9
10
11
12
13
public static void main(String[]
args)
{
int [] dizi ={1, 2, 3, 4, 5};
for(int i: dizi)
System.out.print(i + " ");
}
}
Buradaki i değişkeni, dizimiz içerisindeki her bir elemanı
gösterir. for döngüsünde ise bu, indisi gösterecekti.
Ekran çıktısı:
1
12345
foreach döngüsüne bir örnek daha vererek döngüler dersimizi bitirelim.
//ForeachDongusu2.java - 04.04.2014
1
2
public class ForeachDongusu2
3
{
4
public static void main(String[] args)
5
{
6
int[] dizi = new int[5];
7
for(int a = 0 ; a < 5 ; a++)
8
{
9
dizi[a] = 3 * a + a * a;
10
}
11
int b = 1;
12
for (int a : dizi)
13
{
14
System.out.println("Dizinin " + b + ". elemanı = "
15
+ a);
16
b++;
17
}
18
}
19
}
20
21
Ekran çıktısı:
1
Dizinin 1. elemanı = 0
2
3
4
5
Dizinin 2. elemanı = 4
Dizinin 3. elemanı = 10
Dizinin 4. elemanı = 18
Dizinin 5. elemanı = 28
İlk for döngüsünde dizimizin içini doldurduk.
Diğer for döngümüzde foreach yapısını kullanarak, dizinin elemanlarını ekrana
yazdırdık. Burada i değeri, dizinin içerisindeki elemanı
gösterir. for döngüsündeki gibi adeğerini artırıp dizi[a] diyerek ekrana
yazdırmadık. Buradaki a değeri, döngü içerisinde arka planda artıyor ve her
döngüde, dizinin bir sonraki elemanını gösteriyor.
Bu örneklerimize dizileri de kullanmak zorunda kaldık. Diziler dersimizden
sonra bu örnekleri tekrar incelemeniz yararlı olacaktır.
Ders 27 - Break ve Continue İfadeleri
break ve continue ifadeleri döngümüzün, if else veya switch yapımızın
herhangi bir yerinde kullanılabilir. Örneğin; bir for döngüsünün 1'den 10'a
kadar gittiğini düşünelim. Biz 5'ten sonraki değerleri yazdırmak
istemiyorsak break ifadesini kullanmalıyız. break ifadesi ile bloktan çıkıldığı
gibi döngü de sona erdirilir. breakifadesine switch yapısında çok rastlanır.
Eğer sayı 5'e geldiğinde 5'i atlayarak 6'dan devam edilsin
istiyorsak, continue kullanmamız gerekir.continue ise istenmeyen değerler için
döngünün çalıştırılması istenmiyorsa kullanılır.
break ve continue ifadelerinin kullanımına örnek verelim:
1
//Break.java - 04.04.2014
2
3
public class Break
4
{
5
public static void main(String[] args)
6
{
7
int i = 0;
8
while(true) // sonsuz döngü
9
{
10
if (i == 6)
11
{
12
13
14
15
16
17
18
19
20
21
22
System.out.println("i değeri 6 ya eşit
oldu");
break;
} else {
System.out.println("i değeri: " + i);
i++;
}
}
}
}
Ekran çıktısı:
i değeri: 0
1
i değeri: 1
2
i değeri: 2
3
i değeri: 3
4
i değeri: 4
5
i değeri: 5
6
i değeri 6 ya eşit
7
oldu
Yukarıdaki break örneğinde while (true) ile sonsuz döngüye girdik.
Değişkenimiz 6'ya eşit ise; eşit olduğu ekrana yazdırıldı ve çıkıldı. Eğer eşit
değilse, değişkenin o anki değeri ekrana basıldı ve değeri 1 artırıldı. Bu döngü
sayımız 6 olana kadar dönüyor.
Aşağıdaki continue örneğinde ise, 1'den 10'a kadar for döngüsü kuruldu.
Değişkenimiz olan i sayısı eğer 2'ye tam
bölünmüyorsa; continue ile for döngüsünün bir sonraki değerine atlandı. Eğer
2'ye tam bölünüyorsa değişkenimizin 2'ye bölünebildiği, yani çift sayı olduğu
ekrana bastırıldı.
1
//Continue.java - 04.04.2014
2
3
public class Continue
4
{
5
public static void main(String[] args)
6
{
7
int i = 0;
8
for (i = 1 ; i <= 10 ; i++)
9
{
10
11
12
13
14
15
16
17
18
if(i % 2 == 1)
continue;
else
System.out.println(i + " sayısı 2'ye
bölünür");
}
}
}
Ekran çıktısı:
2 sayısı 2'ye bölünür
1
4 sayısı 2'ye bölünür
2
6 sayısı 2'ye bölünür
3
8 sayısı 2'ye bölünür
4
10 sayısı 2'ye
5
bölünür
for döngüsünden önce i değişkeni tanımlandığı için döngünün
içerisinde int i diye belirtmedik. Eğer ideğişkeni 2'ye tam
bölünüyorsa, continue ile i'nin o anki değeri atlanıp, doğrudan i'nin bir sonraki
değerine geçildi.
Ders 28 - Metod Nedir?
Metodlar, bir programın ayrılmış küçük parçacıkları olarak adlandırılır.
Yapılacak işlemleri, metodlar ile ayrı bir yerde yapabiliriz. Yapılacak olan bu
işlemlerden herhangi bir değer dönebilir veya doğrudan bu işlemler yapılıp
bitirilebilir. Örneğin; kullanıcıdan iki değer alınsın ve bunlar toplansın, daha
sonra ekrana yazdırılsın istiyoruz. Bu işlemleri bir metod ile yapabiliriz. Bu
işlemleri metod içerisinde tanımladıktan sonra, bize sadece o metodu çağırmak
kalır. Burdaki metoda, kullanıcıdan aldığımız iki değeri göndermemiz gerekir.
Çünkü bu iki değeri kullanarak işlem yapması gerekir. Bu tür
metodlara parametreli metodlar denir. Eğer biz bu metoda herhangi bir değer
göndermeden işlem yaptırmak istiyorsak, kullanacağımız
metodlara parametresiz metodlar denir. Şimdi metod kavramını daha
yakından inceleyelim.
Ders 29 - Metod Oluşturma
Genel olarak bir metodun oluşturulma şekli şöyledir:
1
Erişim_Belirleyici Dönüş_Tipi Metod_Adı (parametre listesi)
2
{
3
// Metod gövesi
4
}

Erişim Belirleyici: Metoda nasıl erişileceğini belirtir. Yazmak zorunlu
değildir. Detaylarını ileriki derslerimizde göreceğiz.

Dönüş Tipi: Metoddan dönecek olan değerin tipidir.
Bu int, string, Object gibi tipler olabilir. Metod eğer geriye bir değer
döndürmüyorsa, void olarak tanımlanmalıdır. Eğer döndürüyor ise,
dönüş tipi mutlaka yazılmalıdır.

Metod Adı: Metoda verilecek olan isimdir. Daha sonra bu metodu
çağırmak istediğimizde bu ismi kullanarak çağıracağız.

Parametre Listesi: Bir metoda, kullanılması için göndereceğimiz
değerlerdir. Bu değerlerin sırası ve tipi önemlidir. Gönderilecek olan
bu değerlerin tipi de belirtilmelidir.

Metod Gövdesi: Buraya metodun yapacağı işler yazılır.
Ders 30 - Parametresiz Metodlar
Parametre almayan metodlar, herhangi bir parametre değeri almadan bir kod
bloğunu işleyen metodlardır. Bu metodlar herhangi bir metni ekrana yazabilir,
bir değer döndürebilir ve bunun gibi birçok işlemi yapabilir.
Şimdi parametresiz metodlara bir örnek vererek örnek üzerinden anlatalım:
1
//Metodlar.java - 02.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Metodlar
{
public static void main(String[] args)
{
EkranaYaz();
}
static void EkranaYaz()
{
System.out.println("Bu metod
çağırıldı");
}
}
Ekran çıktısı:
1
Bu metod çağırıldı
Bu örnekte main metodumuzun dışında bir metod oluşturduk. Değer
döndürmediği için tipini void olarak gösterdik. Yani aynı zamanda
bu parametre almayan bir metoddur. Sadece ekrana bir yazı yazdı.
Metodumuzun ismi EkranaYaz olarak belirlendi. Bu metod, ekrana bir yazı
yazdırıyor. Metodumuzu oluşturduktan sonra main metodu içerisinde bu
metodu çağırdık. Çünkü programın başlangıç noktası her
zaman main metodudur ve programlar buradan okunmaya başlar.
Parametre almayan metodlara başka bir örnek verelim:
1
//Metodlar2.java - 02.04.2014
2
3
public class Metodlar2
4
{
5
public static void main(String[]
6
args)
7
{
8
carp();
9
}
10
11
static void carp()
12
{
13
System.out.println(3 * 5);
14
15
16
}
}
Ekran çıktısı:
1
15
Bu programımızda ise carp adında bir metodumuz var. Bu metod; 3 ile 5'i
çarparak ekrana yazdırıyor. Parametre alan metodlarda, bu çarptığımız sayıları
metoda parametre olarak göndereceğiz.
Parametre almayan, fakat geriye değer döndüren metodlara da bir örnek
verelim:
//Metodlar3.java - 02.04.2014
1
2
public class Metodlar3
3
{
4
public static void main(String[]
5
args)
6
{
7
String isim = yaz();
8
System.out.println(isim);
9
}
10
11
static String yaz()
12
{
13
return "Mehmet";
14
}
15
}
16
17
Ekran çıktısı:
1
Mehmet
Parametre almadan da geriye değer döndürülebilir. Eğer geriye değer dönecekse
dönüş tipi, metodun başına yazılmalıdır. Biz burada void yerine String yazdık,
çünkü geriye dönen değer String tipindedir. Daha sonra dönen
değeri isim değişkenine attık ve bunu ekrana yazdırdık. Geriye dönmesini
istediğimiz değerireturn ile kullanıyoruz. Metodun çağrıldığı yere
bu return değeri atanıyor. Bu değeri istersek, doğrudan ekrana yazdırabilirdik.
Bu örnekte dönen değeri değişkene attık.
Ders 31 - Parametreli Metodlar
Bir metoda, kullanması için değerler gönderdiğimizde, bu metod parametreli
metod olur. Aldığı bu parametreler ile işlem yapar. Parametre alan metodlarda,
parantez içerisine parametrenin önce tipi, sonra da adı yazılır. Birden fazla
parametre kullanılacaksa, aralara virgül(,) koyulur.
Parametre alan metodlara ilk örneğimizi verelim:
//Metodlar.java - 02.04.2014
1
2
public class Metodlar
3
{
4
public static void main(String[] args)
5
{
6
hesapla(5, 7); // metoda parametre gönderdik
7
}
8
9
static void hesapla(int a, int b) // metod parametre aldı
10
{
11
System.out.println(a * b); // parametreler çarpılıp ekrana
12
yazıldı
13
}
14
}
15
16
Ekran çıktısı:
1
35
Bu örnekte, parametre alan bir metod kullandık. main metodumuz içerisinde
metodu çağırdık ve parametre olarak 5 ve 7 sayılarını gönderdik. Yani metoda,
bu sayıları al ve işlem yap dedik. İstediğimiz kadar parametre gönderebilirdik.
Parametre gönderirken değerlerin tipini belirtmek zorunda değiliz. Fakat
metodda bu değerleri alırken, parametrelerin tipini belirtmek zorundayız. Bu
örnekte de olduğu gibi alınan parametreler int tipindedir. Aldığı bu değerleri
çarparak ekrana yazdırır.
Bir metod bir parametre alabilir, fakat geriye bir değer döndürme zorunluluğu
yoktur. Parametre alan metodlara başka bir örnek verelim:
1
//Metodlar2.java - 02.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Metodlar2
{
static int x, y;
public static void main(String[] args)
{
int a = 5, b = 2;
islem (a, b);
yaz();
}
static void islem(int a, int b) // parametre alan
metod
{
x = a;
y = b;
}
static void yaz() // parametre almayan metod
{
System.out.println("x değeri: " + x);
System.out.println("y değeri: " + y);
}
}
Ekran çıktısı:
1
x değeri: 5
2
y değeri: 2
Bu örnekte islem() adındaki metod, aldığı parametreleri x ve y değişkenlerine
atıyor. yaz() metodu ise bu değerleri ekrana yazdırıyor. main metodunda ise bu
metodları çağırdık.
Şimdi ise parametre alarak değer döndüren metodlara bir örnek verelim:
1
//Metodlar3.java - 02.04.2014
2
3
public class Metodlar3
4
{
5
static int buyuksayi;
6
public static void main(String[] args)
7
{
8
int x = hesapla(7, 2);
9
10
11
12
13
14
15
16
17
18
19
20
21
22
System.out.println("Büyük olan sayı: "
+ x);
}
static int hesapla(int a, int b)
{
if (a > b)
buyuksayi = a;
else if (a < b)
buyuksayi = b;
return buyuksayi;
}
}
Ekran çıktısı:
1
Büyük olan sayı: 7
Bu örnekte hesap adındaki metodumuz iki parametre alıyor. Aldığı bu
değerlerden büyük olanıhesaplayacak. Bunun için metodun gövdesinde
gövdesinde if yapıları ile bunu sağladık. Hangi sayı büyükse,
onu buyuksayi adlı değişkene atıyor. Daha sonra metod sonunda bu
değeri return buyuksayi; diyerek geri döndürüyor. main metodu içerisinde, bu
metodu içerisinde, bu metodu çağırıyoruz ve bize döndürdüğü değeri, aynı
satırda x adlı değişkene atıyoruz. Son olarak da bu x değişkenini ekrana
yazdırıyoruz. Değer döndüren metodların mantığı bu şekildedir. Yine bu
örnekte buyuksayi adlı değişkenimizi static yaptık. Bunun sebebi ise;
yine static metodlar içerisinden, aynı zamanda da static olmayan bir
değer geri döndürülememesidir.Static Metodlar konusunda bunu daha detaylı
anlatacağız.
String tipindeki parametreli alıp işlem yapan basit bir örnek verelim:
1
//Metodlar4.java - 02.04.2014
2
3
public class Metodlar4
4
{
5
static String adi, soyadi;
// değişkenler static
6
tanımlandı
7
public static void main(String[] args)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
DegerAl("Okan", "Bilke");
yazdir();
}
static void DegerAl(String ad, String soyad)
{
adi = ad;
soyadi = soyad;
}
static void yazdir()
{
System.out.println("Tam isim :" + adi + " " +
soyadi);
}
}
Ekran çıktısı:
1
Tam isim: Okan Bilke
Yukardaki örnekte DegerAl metodu, aldığı
parametreleri adi ve soyadi değişkenlerine atıyor. yazdir()metodu ise,
bu String değişkenleri birleştirerek ekrana yazdırıyor.
Şimdi ise daha detaylı bir örnek verelim:
1
//Metodlar5.java - 02.04.2014
2
3
public class Metodlar5
4
{
5
public static void main(String[] args)
6
{
7
KokBul(1, 0, -9);
8
}
9
static void KokBul(int a, int b, int c)
10
{
11
double delta = b * b - 4 * a * c;
// değişkenler static
12
tanımlandı
13
if(delta > 0)
14
{
15
double x1 = ((-b + Math.sqrt(delta)) / (2 * a)); // ilk kök
16
bulundu.
17
18
19
20
21
22
23
24
25
26
double x2 = ((-b - Math.sqrt(delta)) / (2 * a)); // ikinci kök
bulundu.
System.out.println("2 kök var kökler: " + x1 + " ve " + x2);
} else if (delta == 0)
{
double x1 = (-b) / (2 * a);
// 1 kök bulundu
System.out.println("1 kök var kök: " + x1);
} else if (delta < 0)
System.out.println("Kök yok");
}
}
Ekran çıktısı:
1
2 kök var kökler: 3.0 ve -3.0
Bu örnekteki metodumuz, 2 dereceli bir denklemin delta
yöntemiyle köklerini bulmaktadır. mainmetodumuzda fonksiyona
gönderdiğimiz parametreler, denklemin katsayılarıdır. Doğru sonucu bulması
için de a2 - 9'un katsayılarını verdik. Bu denklemin köklerini 3 ve -3 olarak bize
gösterdi. Eğer deltamız 0'dan büyükse, 2 kökü de buldu. Eğer delta 0 ise; tek
olan kökü buldu ve ekrana gösterdi. Bu metod görüldüğü gibideğer
döndürmemektedir ve tipi void'dir.
Yukarıdaki örnekte a değişkenimiz 1, b değişkenimiz 0 ve c değişkenimiz ise 9'dur.
Şimdiye kadar parametreleri kendimiz verdik. Bir de Scanner sınıfını
kullanarak kullanıcıdan değer alalım ve işlem yapalım:
1
//Metodlar6.java - 02.04.2014
2
3
import java.util.Scanner;
4
5
public class Metodlar6
6
{
7
public static void main(String[] args)
8
{
9
Scanner s = new Scanner(System.in);
10
System.out.println("Bir sayı girin");
11
int deger = s.nextInt();
12
long sonuc = hesapla(deger);
13
14
15
16
17
18
19
20
21
22
23
24
25
26
System.out.println("Çarpım Değeri: " +
sonuc);
}
static long hesapla(int sayi)
{
int carpim = 1;
for(int i = 1 ; i <= sayi ; i++)
{
carpim *= i;
}
return carpim;
}
}
Ekran çıktısı:
1
Bir sayı girin
2
6
3
Çarpım Değeri: 720
Bu örnekte aslında faktöriyel işlemi yaptık. Scanner sınıfı ile kullanıcıdan
aldığımız değeri degerdeğişkenine attık. Bunu da hesapla() metoduna
parametre olarak gönderdik. hesapla() metodunda ise, o sayıya kadar olan tüm
sayıları çarptık ve geriye carpim adlı değişkeni döndürdük. Son olarak da bunu
ekrana yazdırdık.
Scanner sınıfını kullanarak metodlara parametre gönderme örneklerini
çoğaltabiliriz.
Parametre alan ve almayan metodlar için özetleyici bir örnek yapalım.
1
//Metodlar7.java - 02.04.2014
2
3
public class Metodlar7
4
{
5
static void metod1()
6
{
7
System.out.println("Bu metod parametre almıyor ve değer
8
döndürmüyor");
9
}
10
static int metod2()
11
{
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
System.out.println("Bu metod parametre almıyor fakat değer
döndürüyor");
return 5;
}
static void metod3(int a)
{
System.out.println("Bu metod parametre alıyor fakat değer
döndürmüyor");
}
static int metod4(int x)
{
System.out.println("Bu metod parametre alıyor ve değer
döndürüyor");
return x;
}
public static void main(String[] args)
{
metod1();
metod2();
metod3(5);
metod4(10);
}
}
Ekran çıktısı:
Bu metod parametre almıyor ve değer
döndürmüyor
1
Bu metod parametre almıyor fakat değer
2
döndürüyor
3
Bu metod parametre alıyor fakat değer
4
döndürmüyor
Bu metod parametre alıyor ve değer döndürüyor
Bu örnekte 4 farklı kombinasyonu kullandık. Parametre alıp almamasına ve
değer döndürüp döndürmemesine bağlı olarak 4 adet metod yazdık. Daha sonra
sırasıyla hepsini tek tek çağırdık ve çağrılan metodların yaptığı işe göre
çıktılarını aldık.
Ders 32 - Metodlara Dizi Türünden Parametre Geçirmek
Metodlara sadece int, double, String tipinde parametreler gönderilmez. Bu
örneğimizde de parametre olarak dizi gönderelim:
//Metodlar1.java - 02.04.2014
1
2
public class Metodlar1
3
{
4
public static void main(String[]
5
args)
6
{
7
int dizi[] = new int[] {1, 4, 7};
8
IslemYap(dizi);
9
for(int i: dizi)
10
System.out.println(i);
11
}
12
static void IslemYap(int dizi[])
13
{
14
for(int i = 0 ; i < 3 ; i++)
15
{
16
dizi[i] = i * i;
17
}
18
}
19
}
20
21
Ekran çıktısı:
1
0
2
1
3
4
main metodunda bir dizi tanımladık ve elemanlarını atadık. Daha sonra bu
diziyi IslemYap() metoduna gönderdik. Bu metodda da tüm dizinin
elemanlarını, indisinin karesi olacak şekilde değiştirdik. Son
olarakmain metodunda yeni diziyi foreach döngüsü ile yazdırdık.
Dizi türünden parametre geçirme ile ilgili bir örnek daha verelim:
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
//Metodlar2.java - 02.04.2014
import java.util.Scanner;
public class Metodlar2
{
public static void main(String[] args)
{
String dizi[] = new String[3]; // 3 elemanlı dizi tanımlaması
Scanner s = new Scanner(System.in);
for(int i = 0 ; i < 3 ; i++)
{
System.out.println((i + 1) + " . ismi girin: ");
dizi[i] = s.nextLine(); // girilen isimler, diziye atıldı.
}
yazdir(dizi); // dizi, yazdir() metoduna parametre olarak
gönderdik
}
static void yazdir(String dizi[])
{
System.out.println("İsimler: ");
for(String i: dizi)
// diziyi ekrana yazdırdık
System.out.println(i);
}
}
Ekran çıktısı:
1
1 . ismi girin:
2
Okan
3
2 . ismi girin:
4
Onur
5
3 . ismi girin:
6
Göksu
7
İsimler:
8
Okan
9
Onur
10
Göksu
Bu son örneğimizde de kullanıcıdan alınan isimleri diziye attık ve bu diziyi
metoda gönderdik. Bu metodda da isimleri ekrana yazdırdık. Kullanıcıdan veri
alma işlemini Scanner sınıfı ile yaptık. Bunu ilerleyen konularda tekrar
anlatacağız.
Istisnalar:
!
Bir dizi bir metoda gönderilebileceği gibi herhangi bir elemanı da
değiştirilmek üzere metoda gönderilebilir.
Ders 33 - Metodları Aşırı Yükleme (Overloading)
Her bir metod farklı görevler üstlenir ve üstlendiği göreve göre metodlarımızı
isimlendiririz. Fakat farklı işlevler yapan, ama aynı isime sahip olan metodlar
oluştur oluşturmak istediğimizde karşımıza bir konu daha çıkıyor.
Örneğin; int tipinde iki sayıyı çarpan bir hesapla() metodu yapmıştık.
Fakat double tipinde de çarpma yapan bir hesapla metodu oluşturmak
istiyoruz. İşte burada Overloading kavramı ortaya çıkıyor. İki metodumuzun
da isimleri aynı oluyor.
Overloading kavramına göre, aynı isimli iki metod olabilir. Fakat bu
metodların parametre tipleri, parametre sıraları ve sayılarından herhangi birinin
farklı olması gerekir.
Şimdi buna bir örnek verelim:
//Metodlar.java - 02.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Metodlar
{
static int metod1(int sayi)
{
return sayi;
}
static int metod1(int sayi1, int
sayi2)
{
return sayi1;
}
public static void main(String[]
args)
{
System.out.println(metod1(5));
System.out.println(metod1(3,
5));
}
}
Ekran çıktısı:
1
5
2
3
Burada metod1 adında iki tane metod oluşturduk. Aynı isimli metodlar
oluşturmak için bunların parametre sıralarının veya parametre sayılarının veya
tiplerinin farklı olması gerektiğini söylemiştik. Burada biz iki metodumuzun da
parametre sayılarını farklı tuttuk. İlk metod bir parametre, ikinci metod ise iki
parametre almaktadır. Parametre sayılarını değil de parametre tiplerini de farklı
tutabilirdik. Her iki metod da bir parametre alırdı, fakat birisi int tipinde diğeri
ise double tipinde parametre alabilirdi veya sıraları farklı olurdu (double - int).
Bu şekilde de Overloading olurdu.
main metodunda bu iki metodu da ayrı ayrı çağırdık. İlk çağırma işleminde tek
parametre olan 5 değerini gönderdik. Yukarıda da tek değer alan metod çalıştı
ve geriye sayi değişkenini döndürdü. Diğer satırda ise iki parametre alan
metoda 3 ve 5 değerini gönderdik. Yukarıda ise iki parametre alan metod çalıştı
ve bu metod da bize sayi1'i gönderdi. sayi1 ise gönderdiğimiz 3 ve 5
değerlerinden ilki olan 3'tür.
Istisnalar:
!
Overloading yaparken metodların döndürdüğü değerin bir önemi
yoktur. Metodların herşeyi aynı sadece döndürdükleri değer farklı
olsaydı Overloading olmazdı.
Overloading kavramına bir örnek daha verelim:
1
//Metodlar2.java - 02.04.2014
2
3
public class Metodlar2
4
{
5
static int metod1(int sayi1, double sayi2)
6
{
7
return sayi1;
8
}
9
static int metod1(double sayi1, int sayi2) // parametre sırası
10
farklı
11
{
12
return sayi2;
13
}
14
public static void main(String[] args)
15
{
16
System.out.println(metod1(5, 3.6));
17
18
19
20
System.out.println(metod1(6.8, 5));
}
}
Ekran çıktısı:
1
5
2
5
Bu örnekte metod1 adındaki metodumuzu aşırı yükledik. Her iki metod da iki
parametre alıyor, fakat parametrelerin sıraları farklı olduğundan metodların
aşırı yüklenmesine ters bir durum yoktur. mainmetodunda ise ilk olarak 5 ve
3.6 sayılarını gönderiyoruz. Yani ilk perametresi int, diğer
parametresi doubletüründe olan metod çalışacaktır. Bir sonraki satırda ise 6.8
ve 5 değerini gönderiyoruz. Burada da ilk parametresi double, ikinci
parametresi int olan 2. metod çalışıyor. Eğer parametre sıraları farklı
olmasaydı, hangi metodun kullanılacağı bilinemezdi. Overloading yapmanın
amacı da budur.
Sadece döndürdükleri değerleri olan metodların aşırı yüklenmeyeceğini
söylemiştik. Şimdi bir örnek verelim:
1
//Metodlar3.java - 02.04.2014
2
3
public class Metodlar3
4
{
5
static int metod1()
6
{
7
return 6;
8
}
9
static int metod1()
10
{
11
return 5; // hatalı kullanım
12
}
13
public static void main(String[]
14
args)
15
{
16
System.out.println(metod1());
17
System.out.println(metod1());
18
}
19
}
20
Bu örnekte metodlarımızın dönüş tipi aynıdır (int), fakat döndürdüğü değerlerin
farklı olması Overloadingiçin yetmiyor. Bu hatalı bir kullanımdır ve hata
verecektir.
Ders 34 - Metodlarda Özyineleme (Recursion)
Recursion, bir metodun belli bir şart sağlanana kadar kendini sürekli
olarak çağırmasıdır. Faktöriyel örneğini verirsek, normalde for döngüsü ile bir
sayıya kadar olan tüm sayıları çarparak faktöriyel buluyorduk.
Bunu recursive metodlar ile de yapabilmemiz mümkündür. Recursive
metodlar, döngülerin yerine kullanılabilir.
n! = 1 * 2 * 3 * 4 * ... * (n-1)
1
*n
Bu faktöriyel örneğinde en üst sayıdan başlanır ve 1 eksiği ile çarpılır.
İlk olarak faktöriyel örneğini verelim:
//Metodlar.java - 02.04.2014
1
2
public class Metodlar
3
{
4
static int faktoriyel(int sayi)
5
{
6
if(sayi == 1)
7
return 1;
8
else
9
return (sayi*(faktoriyel(sayi 10
1)));
11
}
12
13
public static void main(String[]
14
args)
15
{
16
System.out.println(faktoriyel(5));
17
}
18
}
19
faktoriyel adlı metodda alınan parametre, eğer 1 ise return 1 ile 1 değeri
döndürülüyor. Çarpma işleminde etkisiz eleman 1 olduğu için eğer sayımız 1
ise; sonuç olarak 1 döner ve döngü durur. Eğer 1 değilse gönderdiğimiz
parametre ile bu parametrenin 1 eksiğini çarpmak için faktoriyel(sayi 1) yapıyoruz. Bu sayı gittikçe 1'e ulaştığında tekrar return 1 kısmına giriyor ve
döngüden çıkılıyor.
Recursive metodlar ile yaptığımız bu örneği normal bir döngü ile yapalım:
//Metodlar2.java - 02.04.2014
1
2
public class Metodlar2
3
{
4
static int hesapla(int x)
5
{
6
int deger = 1;
7
for(int i = x ; i > 0 ; i--)
8
{
9
deger *= i;
10
}
11
return deger;
12
}
13
public static void main(String[]
14
args)
15
{
16
System.out.println(hesapla(5));
17
}
18
}
19
20
Ekran çıktısı:
1
120
Bu tür metodlara da iterative metodlar denir. Faktöriyel programını, normal
metod ve döngüler ile bu şekilde yapabiliriz.
Aynı şekilde bir de gönderilen parametreye kadar olan
sayıları toplayan bir recursive metod oluşturalım:
1
//Metodlar3.java - 02.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Metodlar3
{
static int topla(int sayi)
{
if(sayi == 0)
return 0;
else
return (sayi + (topla(sayi - 1))); // kendini sürekli
çağırır.
}
public static void main(String[] args)
{
System.out.println(topla(10));
}
}
Ekran çıktısı:
1
55
Bu örnekte de parametre olarak 10 değeri gönderiyoruz. Eğer parametremiz 0
ise return 0 ile döngüden çıkıyoruz. Nasıl ki çarpmada etkisiz eleman 1 ise,
toplama da etkisiz eleman 0 olduğu için 0 yaptık. Daha sonra eğer sayımız 0
olmadıysa , bu sayı ile sayının 1 eksiğini topluyoruz. Bunun için de return(sayi
- 1) diyerek, sayımızın 1 eksiğini metoda tekrar gönderiyoruz ve böylece kendi
içerisinde dönüyor.
!
Istisnalar:
Recursive metodlar, stack mantığına göre çalışır.
Istisnalar:
!
Recursive fonksiyonların her çağrılışında, değişkenler için bellekte
yeni bir yer ayrılır. Tabiki bu sadece yerel değişkenler için geçerlidir.
Bu recursive metodlar için en çok verilen örneklerden birisini daha
inceleyelim. Fibonacci sayılarını recursive fonksiyonları ile bulabiliriz. İlk
olarak Fibonacci sayılarını recursive fonksiyonlarını ile bulabiliriz. İlk olarak
fibonacci sayılarının ne olduğundan bahsedelim.
0, 1, 1, 2, 3, 5, 8, 13, 21, 34,
1
55...
... şeklinde giden sayılardır. Her sayı, kendinden önceki iki sayının toplamı
şeklinde yazılır. Mesela; 21 sayısı, 13 ile 8'in toplamıdır. Burada 0. eleman
0'dır. 1. eleman 1'dir. 10. eleman ise 55'tir. Bu şekilde devam eder.
Biz istenilen indeksteki sayıyı bulmaya çalışacağız. Yani 23. sayımız hangisi
olduğunu bulmak istersek, nasıl bir recursive metodu yazmamız gerekir şimdi
bunu gösterelim.
//Metodlar4.java - 02.04.2014
1
2
public class Metodlar4
3
{
4
static int fibonacci(int x)
5
{
6
if (x <= 1)
7
return x;
8
else
9
return fibonacci(x - 1) + fibonacci(x - 2);
10
}
11
12
public static void main(String[] args)
13
{
14
System.out.println("6. sayı: " +
15
fibonacci(6));
16
System.out.println("23. sayı: " +
17
fibonacci(23));
18
}
19
}
20
Ekran çıktısı:
1
6. sayı: 8
2
23. sayı: 28657
Eğer metoda gönderdiğimiz değer 1 ve 1'den küçükse, sonuç olarak
gönderdiğimiz değer dönecektir. Eğer 1'den büyükse sayının 1 eksiği ve 2
eksiğinin toplamını geriye değer olarak gönderecektir. mainmetodumuzda ise,
kaçıncı indeksteki sayıyı bulmak istiyorsak, onu parametre olarak göndeririz.
Recursive metodların başka tipleri olsa da temel mantığı bu şekildedir. Daha
karışık ve zor örnekler de verilebilir.
Ders 35 - Static Metodlar
Static metodların iki kullanım amacı vardır. İlk kullanım amacı, her nesne
için aynı işi yapan static bir metod tanımlanır ve bütün nesneler için ayrı ayrı
oluşturulmaz. Böylece bellekten kazanç sağlanır. Diğer kullanım amacı
ise; nesne oluşturmadan sınıf içerisindeki metoda erişmektir. Bu ön bilgiyi
verdikten sonra konumuza giriş yapalım.
Nesne oluşturmadan doğrudan metodlara erişmeye bir örnek verelim:
//Metodlar.java - 03.04.2014
1
2
public class Metodlar
3
{
4
public static int metod(int a, int b)
5
{
6
return a * b;
7
}
8
public static void main(String[] args)
9
{
10
System.out.println(Metodlar.metod(3,
11
5));
12
}
13
}
14
15
Ekran çıktısı:
1
15
Yukarıdaki örneğimizde statik bir metod oluşturduk ve bu metoda
doğrudan sınıfadı.metodadı ile erişebildik. static anahtar kelimesinin bu amaç
için kullanılmasına en iyi örnek Math sınıfının metodlarıdır. Mathsınıfının
metodları, static olarak tanımlanmıştır ve bu metodlara sınıf adı ile erişebiliriz.
Hemen bir örnek verelim:
//Metodlar2.java - 03.04.2014
1
2
public class Metodlar2
3
{
4
public static void main(String[] args)
5
{
6
int a = 3, b = 4;
7
System.out.println((int)Math.pow(a,
8
b));
9
}
10
}
11
12
Ekran çıktısı:
1
81
Math sınıfının metodları kendi içinde static olarak tanımlanmıştır ve sınıf
adı ile erişebiliriz. Yukarıdaki örneğimizde de üs alma işlemi
yapan pow() metodunu, nesne oluşturmadan doğrudan Math.pow() ile
çalıştırabildik.
Şimdi de static metodunun başka bir kullanım amacına bakalım. Statik
metodlar, her nesne için ayrı ayrı oluşturulmaz. Bir statik metod tanımlanır ve
tüm nesneler bu metodu ortak olarak kullanır. Şimdi buna bir örnek verelim:
1
//Metodlar3.java - 03.04.2014
2
3
public class Metodlar3
4
{
5
public static int x;
6
public static void metod(int a)
7
{
8
x = a;
9
}
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[]
args)
{
Metodlar3 m1 = new
Metodlar3();
Metodlar3 m2 = new
Metodlar3();
m1.metod(5);
m1.metod(9);
System.out.println(m1.x);
System.out.println(m2.x);
}
}
Ekran çıktısı:
1
9
2
9
Yukarıdaki örneğimizde static bir metod tanımladık. Oluşturduğumuz iki nesne
ile bu metoda eriştik ve parametre gönderdik. Fakat bu iki nesne için x değerini
yazdırmak istediğimizde ikisini de 9 yazdı. Normalde birine 5 diğerine 9
vermiştik. Bunun sebebi; static metodların nesneye değil, sınıfa ait olmalarıdır.
En son hangi değeri verirsek, artık o değişkenin değeri o olur.
Istisnalar:
!
Eğer herhangi bir yerde, alt sınıflarda bu metodun aynısının
oluşturulmasını istemiyorsak, bu metodlar staticolarak
tanımlanmalıdır. Statik metodların başka bir kullanım amacı da
budur. Fakat bunu ileriki derslerimizde göreceğiz. Çünkü bunun
için kalıtım konusunu iyi bilmemiz gerekiyor.
Istisnalar:
!
!
Statik bir metoddan, static olmayan bir metoda erişilmez. Statik bir
metoddan ise static olan bir metoda erişilebilir.
Istisnalar:
Statik metodlar override ve
overload edilmezler.
MAIN METODU NEDEN STATIC?
Program çalıştığında ilk olaran main metodu çalıştırılır ve bu main metodu da
bir sınıf içerisinde bulunur. Program ilk çalıştığında herhangi bir nesne
oluşturulmaz. Nesne yokken main metoduna erişebilmek için destatic olarak
tanımlanması gerekir ki, doğrudan sınıf adını kullanarak metod netodu
çalışabilsin. Bu yüzdenmain metodu her
zaman static olmalıdır. main metodumuzun public olarak tanımlanmasının
sebebi ise; kodu çalıştıran JVM'nin, bu metoda dışarıdan erişebilmesi
gerekliliğidir.
Buraya kadar oluşturduğumuz static metod ve değişkenleri static olarak
tanımlamamızın sebebi; başka yerde oluşturulmasın diye
değildi. main metodumuzdan bu metodlara erişebilmek için o metodun
da staticolması gerekiyordu. Çünkü biliyoruz ki main metodumuz her
şartta static olmalıdır(Bunun sebebini açıklamıştık). Programların başlama
noktası da bu main metodudur. Bu main metodundan başka metodlara erişmek
gerekiyor. Sadece erişebilmek için metodları static tanımladık. static olan
bu main metodundan,static olmayan bir metoda veya değişkene erişilemez. O
zaman şöyle bir not ekleyebiliriz:
1
//Metodlar4.java - 03.04.2014
2
3
class Sinif1
4
{
5
static int x = 26;
6
static int y = 64;
7
static void yazdir() // static metod tanımlandı
8
{
9
System.out.println("x ve y değişkenleri: " + x + " ve "
10
+ y);
11
}
12
}
13
14
class Sinif2
15
16
17
18
19
20
21
{
public static void main(String[] args)
{
Sinif1.yazdir();
}
}
Ekran çıktısı:
x ve y değişkenleri: 26 ve
1
64
static anahtar kelimesini, nesneye yönelik programlamayı bitirdikten sonra
daha iyi anlayacaksınız. Şuan nesne kavramını bilmiyor olabilirsiniz. O yüzden
bu örneklerde ne demek istediğimiz karmaşık gelebilir. Nesneye yönelik
programlama derslerimizde de Static Metodlara tekrardan bakacağız.
Ders 36 - Dizilere Giriş
Dizi, klasik tanımı ile bünyesinde aynı tip verilerin tutulduğu bir yapıdır.
Diziler ile veriler daha kolay yönetilebilir ve gruplanan bu elemanlara erişim
daha kolay olur. Java'daki diziler, diğer dillerden farklı olarak birer nesnedir.
Bu özelliği ile yüksek performans ve güvenlik sağlar. Diziler sayesinde aynı
tipte olan bu verilerin yönetilmesini kolaylaşır. Günümüzde dizinin yerine,
birçok farklı yapılar olsa da dizilere ihtiyaç duyulmaktadır.
DİZİ TANIMLAMA ŞEKİLLERİ
Java'da dizi tanımlaması şu şekilde yapılır:
int[] dizi; // dizi için referans
1
tanımlandı
Dizi tanımlarken ilk olarak dizideki elemanların tipi belirtilir
(int, String, byte...). Bu dizinin türünü int olarak belirledikten sonra başka
türde veri ekleyemeyiz. Daha sonra köşeli parantezler koyulur. Bu köşeli
parantezler de değişkenimizin bir dizi olduğunu gösterir. Son olarak dizimizin
adı belirlenir. İlerde değişkenlerimize bu dizinin adı ile erişeceğiz. Köşeli
parantez, dizi adından sonra da yazılabilir. Burada dizimizin adı dizi'dir. Birkaç
dizi tanımlamasına daha örnek verelim.
1
int dizi1[];
2
String dizi2[];
3
Object dizi3[];
4
byte dizi4[];
Birden fazla dizi tanımlaması yapmak istiyorsak, bunu aynı satırda yapabiliriz.
Bunun için:
1
int dizi1[], int dizi2[];
Diziyi tanımladık ve şimdi içerisini doldurmamız gerekiyor. Bunun için iki yol
var. Öncelikle diziyi tanımladığımız anda içini dolduralım. Bunun için
kullanacağımız yapı:
int[] dizi = {1, 2, 3, 6, 11, 25, 61,
1
33};
Dizideki elemanları bu yöntemle doldurmak istiyorsak, bunu tanımlandığı
satırda yapmamız gerekir. Aksi halde şu kullanım yanlıştır.
String dizi[];
1
dizi = {"Okan", "Bilke"};
2
// bu derleme hatasına sebep olur. İlk satırda dizi
3
doldurulmalıydı
Bu yanlış kullanımda da görüldüğü gibi bu şekilde dizi oluşturmak ve
doldurmak yanlıştır. Bunun için bu yöntemde dizi oluşturacaksak, ilk satırda
diziyi doldurmalıyız.
String dizi[] = {"Okan",
1
"Bilke"};
Dizi oluşturmanın bir diğer yöntemi de new anahtar sözcüğünü kullanmaktır.
int[] dizi = new int[10]; // dizi doldurulmadıysa eleman sayısı
1
belirtilir
Oluşturduğumuz dizinin 10 elemanlı olduğunu gösterdik ve nesnemizi
oluşturduk. Diziyi new ile oluşturursak eleman sayısı belirtmemiz zorunludur.
Artık programımızın istediğimiz yerinde dizimize eleman atayabiliriz. Java'da
diziler referans tipli nesneler oldukları için new anahtar sözcüğü ile de
oluşturulabilirler. Yani diziler nesne oldukları için nesne oluşturmada
kullanılan new ile de dizileri oluşturabiliriz.
Dizi doldurmada anlattığımız ilk yöntemde, dizi elemanlarını ilk satırda
doldurmamız gerektiğini söylemiştik. Eğer ilk satırda doldurmazsak, herhangi
bir satırda new anahtar sözcüğünü kullanarak da doldurabiliriz. Bunun için:
int dizi[];
// referans oluşturuldu
1
dizi = new int[] {1, 4, 7, 2, 9}; // dizi doldurulduysa eleman sayısı
2
belirtilmez
Burada görüldüğü gibi ilk satırda elemanları doldurmadık. Başka bir satırda
doldurabilmek için new ile nesne oluşturmalıyız. Normalde diziyi sadece
tanımlarsak, dizi için bir referans oluşturmuş oluruz. Daha sonra new ile
diziyi oluşturunca da dizi için bir nesne oluşturmuş oluruz.
DİZİ ELEMANINA ERİŞME
Dizideki her elemanın bir indisi vardır. Dizideki elemanlara bu indis ile erişilir.
Dizilerin indisi 0'dan başlar.
Bir dizinin elemanına erişmek için parantez içerisine, erişmek istenen
elemanın indisi yazılır.
int[] dizi = {1, 2, 3, 6, 11, 25, 61,
1
33};
Örnek verirsek:
1
//DizilereGiris.java - 04.04.2014
2
3
public class DizilereGiris
4
{
5
6
7
8
9
10
11
12
public static void main(String args[])
{
int[] dizi = {1, 2, 3, 6, 11, 25, 61, 33};
System.out.println(dizi[3]); // 4. elemana
erişildi
}
}
Ekran çıktısı:
1
6
Dizinin 3. indisine erişmek istiyoruz. Diziler 0. indisten başladığı için aslında
bu, 4. elemana karşılık geliyor.
Şimdi de new ile ayrı bir satırda dizimizi doldurarak, dizi içerisindeki bir
elemana erişelim:
//DizilereGiris2.java - 04.04.2014
1
2
public class DizilereGiris2
3
{
4
public static void main(String args[])
5
{
6
int dizi[];
7
dizi = new int[] {1, 2, 3}; // new ile ayrı satırda
8
doldurulabilir.
9
System.out.println(dizi[1]);
10
}
11
}
12
13
Ekran çıktısı:
1
2
Bu örnekte görüldüğü gibi dizimizi tanımladık ve new ile dizimizi ayrı bir
satırda doldurduk. Daha sonra da dizimizin 1. indisli elemanına, yani 2.
elemanına ulaştık. Normalde köşeli parantezler içerisine dizimizin kaç elemanlı
olduğunu yazıyorduk, fakat bu örnekte zaten elemanları doğrudan
belirlediğimiz için eleman sayısını yazmasak da hata vermez.
DİZİ ELEMANLARINI LİSTELEME
İçerisi doldurulmuş bir dizinin elemanlarını basit olarak bir for döngüsü ile
listeleyebiliriz. Örnek verirsek:
//DizilereGiris3.java - 04.04.2014
1
2
public class DizilereGiris3
3
{
4
public static void main(String
5
args[])
6
{
7
int dizi[] = new int[5];
8
dizi = new int[] {1, 6, 9, 3, 2};
9
for(int a = 0 ; a < 5 ; a++)
10
{
11
System.out.println(dizi[a]);
12
}
13
}
14
}
15
16
Ekran çıktısı:
1
1
2
6
3
9
4
3
5
2
Bu örnekte dizimizin eleman sayısını 5 olarak belirlediğimiz için döngümüzü
5'e kadar devam ettirdik. İlerde dizinin uzunluğunu bulmayı anlattıktan sonra
uzunluğunu kullanarak da elemanları listeleyeceğiz.
Dizilerin elemanlarına bir for ile eriştik. for döngüleri ile erişmenin yanında
kısa yol olan foreach döngüleri ile de erişilebilir. Buna bir örnek verelim:
1
//DizilereGiris4.java - 04.04.2014
2
3
public class DizilereGiris4
4
{
5
public static void main(String args[])
6
7
8
9
10
11
12
13
14
15
16
17
{
int array[] = {11, 22, 33, 44};
for(int i: array)
System.out.println(i);
String array2[] = {"Okan", "Bilke",
"ElektroArge"};
for(String i: array2)
System.out.println(i);
}
}
Ekran çıktısı:
1
11
2
22
3
33
4
44
5
Okan
6
Bilke
7
ElektroArge
Bu örnekte for döngüsünü kurduk ve döngünün içinde bir değişken tanımladık.
Bu değişken dizinin elemanlarını tutuyor. Normal for döngüsünde indis tuttuğu
için array[i] diyerek elemana erişebiliyorduk.
Dizimiz String ise for içerisindeki değişkenimiz de String olmalı. Yani
dizimizin tipi ile değişkenimizin tipi aynıolmak zorundadır.
Çünkü int tipindeki bir değişken String tipli tanımlanmış bir dizideki elemanı
tutamaz.
Istisnalar:
!
1
2
3
4
Java'da int ve byte tipindeki diziler için bir istisna vardır. Bu tipteki
dizilere, ' (tek tırnak) içerisinde bir karakteri eleman olarak
ekleyebiliriz. Bu elemanı ekrana bastırmak istersek, ASCII kodunu
gösterecektir.
//DizilereGiris5.java - 04.04.2014
public class DizilereGiris5
{
5
6
7
8
9
10
11
12
public static void main(String
args[])
{
int dizi[] = new int[] {1, '2', 3};
System.out.println(dizi[1]);
}
}
Ekran çıktısı:
1
50
Bir önceki örnekteki değerleri değiştirerek yeni bir örnek yazdık. Notumuzda
anlattığımız gibi bir elemanı tek tırnak içerisinde yazdık. Daha sonra bu
elemanı ekrana yazdırdığımızda ASCII kodunu çıktı olarak aldık.
Istisnalar:
!
Java dilinde diziler, referans tipli oldukları için belleğin heap alanında
tutulurlar.
OBJECT SINIFINDAN DİZİ OLUŞTURMA
Dizilerimizde aynı tipten verileri tutabiliriz demiştik. Fakat bir istisna var.
Java'da her sınıf Objectsınıfından türetildiği için karşımıza bu istisna çıkıyor.
Eğer dizimizi Object sınıfından oluşturursak içerisine farklı tipte verileri
ekleyebiliriz.
Örnek vererek gösterelim:
1
//DizilereGiris6.java - 04.04.2014
2
3
public class DizilereGiris6
4
{
5
public static void main(String args[])
6
{
7
Object dizi[] = new Object[3];
8
dizi[0] = "Mehmet";
9
dizi[1] = 2;
10
dizi[2] = 444.3;
11
12
for(int a = 0 ; a < 3 ; a++)
13
14
15
16
17
System.out.println((a + 1) + ". eleman: " +
dizi[a]);
}
}
Ekran çıktısı:
1
1. eleman: Mehmet
2
2. eleman: 2
3
3. eleman: 444.3
Dizimizi Object sınıfından oluşturduk. Böylece dizimizde farklı tipteki verileri
barındırdık.
Java'da basit bir örnek için oluşturduğumuz sınıf bile Object sınıfından
türemiştir.
Ders 37 - Bir Dizinin Boyutu
Bir dizinin boyutu, o dizideki eleman sayısıdır. Dizinin boyutunu bulmak için
dizilerin length özelliği kullanılır. Aşağıdaki kod, dizinin boyutunu ekrana
basacaktır.
//BirDizininBoyutu.java 1
04.04.2014
2
3
public class BirDizininBoyutu
4
{
5
public static void main(String
6
args[])
7
{
8
int dizi[] = {1, 2, 'a', 5};
9
System.out.println(dizi.length);
10
}
11
}
12
Ekran çıktısı:
1
4
Dizimizde 4 eleman olduğu için çıktımızı 4 olarak aldık. Fakat dediğimiz gibi 4
elemanlı bir dizinin en fazla 3. indisine ulaşabiliriz. Bunun sebebinin ise;
dizilerin indisinin 0'dan başlaması olduğunu söylemiştik.
Şimdi dizilerin boyutunu kullanarak bir örnek yapalım:
//BirDizininBoyutu2.java - 04.04.2014
1
2
public class BirDizininBoyutu2
3
{
4
public static void main(String args[])
5
{
6
int dizi1[];
7
dizi1 = new int[6];
8
for(int a = 0 ; a < 6 ; a++)
9
{
10
dizi1[a] = a * a;
11
}
12
for(int a = 0 ; a < dizi1.length ; a++)
13
System.out.println("Dizinin " + a + ". elemanı: " +
14
dizi1[a]);
15
}
16
}
17
18
Ekran çıktısı:
Dizinin 0. elemanı: 0
1
Dizinin 1. elemanı: 1
2
Dizinin 2. elemanı: 4
3
Dizinin 3. elemanı: 9
4
Dizinin 4. elemanı:
5
16
6
Dizinin 5. elemanı:
25
Yukarıdaki örnekte dizi1 adında bir dizi tanımladık ve ilk değer ataması
yapmadık, sadece tanımını yaptık. Bu yüzden bu diziye eleman yerleştirmek
istediğimizde new anahtar sözcüğü ile referans ataması yapmamız ve dizi
boyutunu vermemiz gerekir. O satırda diziyi doldurmayacaksak boyut verilmez.
Daha sonra for döngüsü içerisinde dizinin her elemanına, o
elemanının indisinin karesini değer olarak verdik. Diziyi doldurma işlemini
tamamladıktan sonra dizinin uzunluğu kadar döngü kurarak elemanları
yazdırdık.
Bir dizinin uzunluğunun dışında bir işlem yaptığımızda uyarı ile karşılaşırız.
Mesela; 3 elemanlı bir dizinin 3. indisli elemanına ulaşmak istersek, hata verir.
Bu hata java.lang.ArrayIndexOutOfBoundsExceptionhatasıdır. Bunu örnek
üzerinde gösterelim:
//BirDizininBoyutu3.java 1
04.04.2014
2
3
public class BirDizininBoyutu3
4
{
5
public static void main(String
6
args[])
7
{
8
String dizi[] = {"a", "b", "c"};
9
System.out.println(dizi[3]);
10
}
11
}
12
Ekran çıktısı:
Exception in thread "main"
1
java.lang.ArrayIndexOutOfBoundsException: 3
2
at BirDizininBoyutu2.main(BirDizininBoyutu2.java:8)
Burada 3 elemanlı bir String dizimiz var. Fakat diziler 0. indisten başladığı için
en son elemanın indisi 0 olur. Biz ise 3. indise ulaşmak istediğimiz için hata
aldık.
Ders 38 - Dizileri Kopyalama
Java'da dizileri başka bir diziye kopyalamak isteyebiliriz. Bunu yapabilmek için
iki yöntem vardır. İlk yöntem klasik olarak for döngüsü ile bir dizinin
elemanlarını diğer diziye atarak yapılır.
Anlattığımız ilk yöntem ile ilgili bir örnek verelim:
//DizileriKopyalama.java 04.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DizileriKopyalama
{
public static void main(String
args[])
{
int dizi1[] = new int[4];
for(int a = 0 ; a < dizi1.length ;
a++)
dizi1[a] = a + a;
int[] dizi2 = new
int[dizi1.length];
for(int a = 0 ; a < dizi1.length ;
a++)
dizi2[a] = dizi1[a];
for(int a = 0 ; a < dizi2.length ;
a++)
System.out.println(dizi2[a]);
}
}
Ekran çıktısı:
1
0
2
2
3
4
4
6
Yukarıdaki örnekte diziyi doğrudan kopyaladık. İlk for döngüsünde dizi1'in
içini doldurduk. İkinci fordöngüsünde dizi2'nin içerisini, dizi1'in eleman sayısı
kadar döngü kurarak doldurduk. Son for döngüsünde ise yeni dizinin
elemanlarını yazdırdık.
SYSTEM.ARRAYCOPY METODU İLE DİZİYİ KOPYALAMA
Dizi kopyalamadaki 2. yöntem ise; System.arraycopy() metodudur. Şimdi bu
yönteme bir örnek verelim:
1
//DizileriKopyalama2.java - 04.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class DizileriKopyalama2
{
public static void main(String args[])
{
int dizi1[] = {1, 3, 5, 7, 9};
int dizi2[] = new int[5];
System.arraycopy(dizi1, 0, dizi2, 0, 5); // hazır metod
for(int a = 0 ; a < dizi2.length ; a++)
System.out.println("Yeni dizinin " + a + ". elemanı: " +
dizi2[a]);
}
}
Ekran çıktısı:
1
Yeni dizinin 0. elemanı: 1
2
Yeni dizinin 1. elemanı: 3
3
Yeni dizinin 2. elemanı: 5
4
Yeni dizinin 3. elemanı: 7
5
Yeni dizinin 4. elemanı: 9
System.arraycopy(dizi1, 0, dizi2, 0, 5}; metodu ile tek satırda kopyalama
yaptık.
Bu Metodun Kullanım Şekli:
System.arraycopy(kaynak dizi, kaynak dizinin başlangıç
1
indisi,
hedef dizi, hedef dizinin başlangıç indisi, adedi);
Şimdi buradaki kavramları açıklayalım.

Kaynak dizi = Kaynak dizinin adı yazılır.

Kaynak dizinin başlangıç indisi = Kaynak dizinin kaçıncı indisli
elemanından itibaren kopyalanacağı belirtilir. Biz ilk elemandan
itibaren kopyalanmasını istediğimiz için 0 yazdık.

Hedef dizi = Hangi diziye kopyalayacaksak o dizinin adı yazılır.

Hedef dizinin başlangıç indisi = Kaynak diziyi, hedef dizinin kaçıncı
indisinden itibaren kopyalanacağını belirtir. Biz bu örnekte
kopyalamayı, hedef dizinin ilk indisinden başlayarak yapsın istedik.

Adedi = Kopyalanacak olan dizi elemanlarının sayısını belirtir.
Ders 39 - Dizileri Sıralama
Dizileri sıralamak için birçok yöntem ve algoritma vardır. Biz bu
konuyu Array.sort() metodunu kullanarak anlatacağız.
ARRAY.SORT METODU İLE DİZİYİ SIRALAMA
Dizileri sıralamak için Arrays sınıfının sort() metodu kullanılır. Bu metodu
kullanmak istediğinizde Eclipse,
sizden java.util.Arrays paketini import etmenizi isteyecektir. Bu metodu
kullanabilmek için bu paketi importetmek gerekir. Şimdi dizileri sıralamaya
örnek vererek açıklayalım:
1
//DizileriSıralama.java - 04.04.2014
2
3
import java.util.Arrays; // import Edildi
4
5
public class DizileriSıralama
6
{
7
public static void main(String args[])
8
{
9
int[] dizi = {1, 6, 8, 3};
10
Arrays.sort(dizi); // dizi sıralandı
11
for(int a = 0 ; a < dizi.length ; a++)
12
System.out.println(dizi[a]);
13
}
14
}
15
16
Ekran çıktısı:
1
1
2
3
3
6
4
8
Dizi içerisinde karışık olarak verilmiş sayıları küçükten
büyüğe sıraladık. Arrays sınıfının başka metodları kullanılarak diziler üzerinde
işlemler yapılabilir.
Bu metod diziyi baştan sona sıralar. Fakat çok kullanılmasa da dizinin belirli bir
kısmını sıralamak istersek ne yapmamız gerekir. Yine aynı metodu
kullanacağız fakat birkaç parametre vereceğiz.
//DizileriSıralama2.java - 04.04.2014
1
2
import java.util.Arrays; // import Edildi
3
4
public class DizileriSıralama2
5
{
6
public static void main(String args[])
7
{
8
int[] dizi = {1, 8, 6, 3, 7, 2};
9
Arrays.sort(dizi, 1, 4);
// parametre verilerek dizi
10
sıralandı
11
for(int a = 0 ; a < dizi.length ; a++)
12
System.out.println(dizi[a]);
13
}
14
}
15
16
Ekran çıktısı:
1
1
2
3
3
6
4
8
5
7
6
2
Burada verdiğimiz 1 ve 4 parametreleri, 1. ile 4. elemanlar arasındakileri
sıralar. Kalan değerler sırasızolarak yazılır. Görüldüğü gibi ilk dört elemanı
sıraladı ve kalan iki elemanı sırasız bir şekilde aynen yazdı.
Dizileri sıralamak için hazır metodları kullanmak yerine kendimiz de bir
algoritma geliştirebiliriz.
Ders İçinde Yazılmış Tüm Programlar ve Kodları Ektedir:
Ders 40 - Dizilerde Arama
Java'da diziler içerisinde bir elemanı aratmak için kullanacağımız
yöntem binarySearch yöntemidir.
BİNARYSEATCH YÖNTEMİ İLE DİZİLERDE ARAMA İŞLEMİ
Bu metod ile aratılan elemanın dizideki indisi bulunur. Eğer eleman dizide
yoksa negatif bir değer döner. Kullanacağımız metod Arrays sınıfına
ait binarySearch() metodudur. Bu hazır bir metoddur. Bunun yanında farklı
arama algoritmaları geliştirilebilir.
Bu metod ile dizilerde arama yapmak istersek dizilerin sıralı olması gerekir.
Yani bir diziyi önce sıralayıp daha sonra arama yapmamız gerekir. Tabi bu
yöntemle arama yapacaksak bu geçerlidir. Eğer sıralamazsak istediğimiz
elemanı bulamaz. Bulduğu elemanın indisi, sıralandıktan sonraki indisidir.
//DizilerdeArama.java - 04.04.2014
1
2
import java.util.Arrays;
3
4
public class DizilerdeArama
5
{
6
public static void main(String args[])
7
{
8
int dizi[] = {3, 4, 12, 9, 2, 5};
9
Arrays.sort(dizi); // önce dizi sıralandı
10
int deger = Arrays.binarySearch(dizi, 12); // 12 elemanı
11
aranıyor
12
if (deger < 0)
13
System.out.println("Bulunamadı");
14
else
15
System.out.println("Bulundu ve indisi: " + deger);
16
}
17
}
18
19
Ekran çıktısı:
1
Bulundu ve indisi: 5
Bu örnekte önce diziyi sıraladık. Daha sonra Arrays.binarySearch(dizi,
12) metodunu kullanarak 12 değerini dizi adlı dizide arattık. Bize bir değer
dönecek. Bu değeri de deger değişkenine attık. Eğer elemanımız dizide
yoksa; negatif bir değer dönecektir ve biz de bunu if ile kontrol ettik. Eğer
negatif ise "Bulunamadı" diye bir çıktı yazdırdık. Burada bize 5 değeri döndü.
Bu değer, dizi sıralandıktan sonra, 12değerinin yeni indisidir.
Ders 41 - Dizileri Karşılaştırma
Herhangi bir yerde iki diziyi karşılaştırmak isteyebiliriz. Dizileri
karşılaştırabilmek için karşılaştıracağımız iki dizinin de aynı tipte olması
gerekir. Boolean, byte, char, Ooject, int, long, short ve float tipindeki dizileri
karşılaştırabiliriz. Dizileri karşılaştırmak için
yine Arrays sınıfının equals() metodunu kullanmamız gerekir.
ARRAYS.EQUALS METODU İLE DİZİLERDE EŞİTLİK KONTROLÜ
Bu metodu kullanmamız için java.util.Arrays paketini import etmemiz
gerekir. Bu metod, dizileri karşılaştırdıktan sonra eşitse true;
değilse false döndürür.
Dizi karşılaştırmaya örnek verirsek:
//DizileriKarsilastirma.java - 04.04.2014
1
2
import java.util.Arrays;
3
4
public class DizileriKarsilastirma
5
{
6
public static void main(String args[])
7
{
8
char[] dizi = {'r'};
9
char[] dizi2 = {'y'};
10
System.out.println(Arrays.equals(dizi,
11
dizi2));
12
}
13
}
14
15
Ekran çıktısı:
1
false
Bu örnekte karşılaştırma yapmak istediğimiz dizinin tipini char olarak
ayarladık ve karşılaştırma yapıp sonucu doğrudan ekrana yazdırdık.
Başka tipte bir dizi örneği verelim:
//DizileriKarsilastirma2.java - 04.04.2014
1
2
import java.util.Arrays;
3
4
public class DizileriKarsilastirma2
5
{
6
public static void main(String args[])
7
{
8
int[] dizi = {43, 12};
9
int[] dizi2 = {43, 12};
10
System.out.println(Arrays.equals(dizi,
11
dizi2));
12
}
13
}
14
15
Ekran çıktısı:
1
true
Dizilerin eşit olabilmesi için hem eleman sayılarının hem de elemanlarının
aynı olması gerekir.
Ders 42 - Çok Boyutlu Diziler
Önceki dizi derslerimizde tek boyutlu diziler kullandık. Boyut kavramını şu
şekilde anlatalım. Matrislerde satırlar ve sütunlar vardır. 4x4'lük bir matrisin
bütün elemanlarını bir diziye koyarsak, 2. satırın 3. elemanına erişmek
isteseydik, bunu tek boyutlu diziler ile yapamazdık. Yapsak bile özel
fonksiyonlar oluşturmamız gerekirdi. Bunu uzay
sistemindeki x ve y koordinatları gibi düşünebiliriz. Buna 2 boyutlu dizi denir.
Dizideki satırlar dizinin bir indisini, sütunlar ise dizinin diğer indisini oluşturur.
Eğer bu 2. satır 3. sütundaki elemanın da kendi içerisinde bir dizi
oluşturduğunu düşünürsek, bu şekilde oluşan dizilere de n boyutlu dizi denir.
ÇOK BOYUTLU DİZİ TANIMLAMASI
Örnek olarak Java'da 2 boyutlu dizi tanımlamasını verelim.
int dizi[][] = new int[3][3]; // 3 satır 3 sütunlu iki boyutlu bir dizi
1
tanımlandı
Kaç boyutlu bir dizi kullanacaksak, o kadar köşeli parantez kullanmalıyız. Tek
boyutlu diziler için [], 2 boyutlu diziler için [][], 3 boyutlu diziler için ise [][][]
kullanılır. 3 boyutlu olanlardan daha fazlası genelde kullanılmaz. 3 boyutlu bir
dizi tanımlaması yapacak olursak:
1
byte UcBoyutluDizi[][][] = new byte [2][3][4];
Bunu 3 boyutlu uzay gibi düşünürsek x'i 2, y'yi 3 ve z boyutunu ise 4 karşılar.
Çok boyutlu diziler, dizi içinde dizi gibidir. Dizideki bir elemanın içerisinde
birkaç eleman varsa bu çok boyutlu dizi olur.
ÇOK BOYUTLU DİZİ ELEMANLARINA ERİŞİM
Çok boyutlu dizi elemanlarına erişmek için matris örneğini verelim. Çok
boyutlu dizi elemanlarına erişim, tek boyutlu dizilerdeki erişime benzer
yapıdadır. Köşeli parantezler içerisine indeksler yazılır.
//CokBoyutluDiziler.java - 04.04.2014
1
2
public class CokBoyutluDiziler
3
{
4
public static void main(String args[])
5
{
6
int matris[][] = new int [][] {{3, 6}, {5,
7
7}};
8
// çok boyutlu dizi tanımlaması
9
System.out.println(matris[1][1]);
10
}
11
}
12
13
Ekran çıktısı:
1
7
Matrisi tanımladıktan sonra matris[1][1] ile matris adındaki bir dizinin bir
nevi 1. indisli elemanının tekrar 1. indisli elemanına eriştik. Dizimizde iki
eleman var. İlk eleman {3, 6}'dır. Bunun indisi 0'dır. İkinci elemanımız ise {5,
7}'dir. Bunun indisi ise 1'dir. Java'da dizilerde indislerin sıfırdan başladığını
söylemiştik. Daha sonramatris[1][1] ile 1. indisli eleman olan {5, 7}'nin
içerisinde 1. indisli eleman olan 7'ye ulaştık. Yani çok boyutlu dizilerde dizinin
elemanı içerisinde tekrar başka bir elemanına erişebiliyoruz. Matris mantığı da
bu şekildedir. 2 boyutlu dizi içinde konuşursak, satırlar dizinin bir elemanı, bu
satırlar içerisindeki elemanlar da (sütun) dizinin 2. elemanıdır.
Buna bir örnek verirsek:
//CokBoyutluDiziler2.java - 04.04.2014
1
2
public class CokBoyutluDiziler2
3
{
4
public static void main(String args[])
5
{
6
String dizi[][] = {{"okan", "bilke"}, {"1",
7
"2"}};
8
System.out.println("Dizinin 2. elemanları: ");
9
System.out.println(dizi[1][0] + " ve " +
10
dizi[1][1]);
11
}
12
}
13
Ekran çıktısı:
1
Dizinin 2. elemanları:
2
1 ve 2
Dizimizde iki eleman var. Bunlardan ilki okan ve bilke'dır. Diğer eleman ise 1
ve 2'dir. Biz 2. elemana ulaşmak istiyoruz, yani 1 ve 2'ye. Bunun için indis
olarak 1 yazmamız lazım. Bu 2. elemanının içerisinde de elemanlar olduğu için
bu elemanların her birine de 0 ve 1 indisleri ile ulaşmamız gerekiyor.
!
Istisnalar:
Eğer değeri atanmamış bir elemana erişmek istersek, o dizinin tipi ne
ise o tipin default değeri yazdırılır.
Bu anlattığımız özelliği örnek üzerinde gösterelim:
//CokBoyutluDiziler3.java 05.04.2014
1
2
public class CokBoyutluDiziler3
3
{
4
public static void main(String
5
args[])
6
{
7
int dizi1[] = new int[1];
8
String dizi2[] = new String[1];
9
boolean dizi3[] = new
10
boolean[1];
11
System.out.println(dizi1[0]);
12
System.out.println(dizi2[0]);
13
System.out.println(dizi3[0]);
14
}
15
}
16
Ekran çıktısı:
1
0
2
null
3
false
Bu örnekte üç farklı tipten üç tane dizi oluşturduk ve hiçbirine eleman
atamadık. Daha sonra bu dizileri ekrana yazdırmak istediğimizde int tipi
için 0, String tipi için null, boolean tipi için ise false değerini ekrana yazdırdı.
Çünkü bunlar, bu tiplerin varsayılan değerleridir. Yani bunlar için bir eleman
belirlemezsek, varsayılan olanları kullanır.
Tabi burada şunu söyleyelim. Dizilerimiz new ile oluşturuldukları için bu
şekilde default değer atandı. Eğer new ile oluşturmayıp ekrana yazdırmak
isteseydik, aşağıdaki gibi altını çizecekti.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//CokBoyutluDiziler3.java - 05.04.2014
public class CokBoyutluDiziler3
{
public static void main(String args[])
{
int dizi1[[];
String dizi2[];
Boolean dizi3[]
System.out.println(dizi1[0]);
System.out.println(dizi2[0]);
System.out.println(dizi3[0]);
}
}
ÇOK BOYUTLU DİZİLERİ LİSTELEME
Çok boyutlu dizilere erişme mantığı, tek boyutlu dizilere erişme ile aynıdır.
Şuana kadar anlattığımız özelliklerin de olduğu bir örnek verelim ve çok
boyutlu dizimizi listeyelim:
1
//CokBoyutluDiziler4.java - 05.04.2014
2
3
public class CokBoyutluDiziler4
4
{
5
public static void main(String args[])
6
{
7
int dizi[][] = new int[3][3];
8
for(int a = 0 ; a < 3 ; a++)
9
for(int b = 0 ; b < 3 ; b++)
10
{
11
dizi[a][ b] = a + b;
12
System.out.println("Dizi[" + a + "][" + b + "] =" +
13
dizi[a][ b]);
14
}
15
for(int a = 0 ; a < 3 ; a++)
16
{
17
for(int b = 0 ; b < 3 ; b++)
18
{
19
System.out.print(dizi[a][ b] + "\t");
20
// \t ile 8 karakter boşluk bırakıldı
21
}
22
23
24
25
26
System.out.println("");
}
}
}
Ekran çıktısı:
1
Dizi[0][0] =0
2
Dizi[0][1] =1
3
Dizi[0][2] =2
4
Dizi[1][0] =1
5
Dizi[1][1] =2
6
Dizi[1][2] =3
7
Dizi[2][0] =2
8
Dizi[2][1] =3
9
Dizi[2][2] =4
10
0 1 2
11
1 2 3
12
2 3 4
Bu örnekte iç içe olan ilk iki for döngüsünde, dizinin her elemanına değer
olarak, bulunduğu satır ve sütun indislerinin toplamını verdik. Daha sonraki iç
içe iki for döngüsünde ise elemanları 3x3 matris şeklinde yazdırdık.
Çok boyutlu diziler için söyleyeceğimiz başka bir özellikten bahsedersek çok
boyutlu dizilerde diziler tanımlandıktan sonra tek boyutlu dizilerdeki gibi
eleman ekleyebiliriz. Bunun için new anahtar sözcüğünü kullanmamız
gerekiyor.
1
//CokBoyutluDiziler5.java - 05.04.2014
2
3
public class CokBoyutluDiziler5
4
{
5
public static void main(String args[])
6
{
7
String dizi[][];
// dizi için referans tanımlaması
8
dizi = new String[2][2]; // new ile dizi nesnesi
9
oluşturuldu
10
dizi[0][0] = "Okan";
11
dizi[0][1] = "Bilke";
12
dizi[1][0] = "Elektro";
13
dizi[1][1] = "ARGE";
14
System.out.println("Dizinin elemanları: ");
15
16
17
18
19
20
21
22
23
24
25
for(int a = 0 ; a < 2 ; a++)
{
for(int b = 0 ; b < 2 ; b++)
{
System.out.print(dizi[a][ b] + "\t");
}
System.out.println("");
}
}
}
Ekran çıktısı:
1
Dizinin elemanları:
2
Okan Bilke
3
Elektro ARGE
Burada dizimiz için referans tanımlaması yaptıktan sonra new ile nesne
oluşturduk ve dizimizin kaç elemanlı olacağını belirledik. Daha sonra her
elemana bir değer atadık. Daha sonra for döngüsü ile de dizimizin elemanlarını
matris şeklinde yazdırdık.
ÇOK BOYUTLU DİZİNİN UZUNLUĞU
Tek boyutlu dizilerde uzunluk bulmayı anlatmıştık. Çok boyutlu dizilerde de bu
yöntem aynıdır. Uzunluk bulmak için length özelliği kullanılır. Fakat farklı
olarak, dizilerdeki her eleman içerisinde birçok eleman olduğu için bu
elemanların da uzunluğunu bulabiliriz. Bunu bir örnekle açıklayalım:
1
3
2
2
3
2
4
3
Burada dizi adındaki dizimiz 3 elemanlıdır. O yüzden ilk çıktımızda 3
verecektir. Dizimizin 0. ve 1. indisli elemanları kendi içerisinde 2 elemana
sahiptir, bu yüzden diğer iki çıktı ise 2 olacaktır. Son elemanımızın içerisinde
de 3 eleman olduğu için son çıktımız 3'tür.
Ders 43 - String[] Args Dizisi
Programlarımızı ilk olaran main metodu içerisinden başlar. main metodumuz
ise String tipinde argsadında bir tek boyutlu diziyi parametre parametre olarak
alır.
Bunu argüman olarak yazmadığımızda, yani main metodunda parantezler
içerisini boş bıraktığımızda programlarımız çalışacak mı? Bir örnek ile
başlayalım.
1
//MainParametresi.java - 05.04.2014
2
3
public class MainParametresi
4
{
5
public static void main() // parametre vermedik
6
{
7
System.out.println("Main Metodu");
8
}
9
}
10
11
Ekran çıktısı:
Error: Main method not found in class MainParametresi, please define the main
1
method as:
2
public static void main(String[] args)
Görüldüğü gibi hiçbir parametre vermediğimiz zaman hata ile
karşılaşıyoruz. main parametresi, Stringtipinde bir tek boyutlu diziyi parametre
olarak almak zorundadır. Peki, bu argümanımızın adı args olmak zorunda mı?
Dizimizin adı önemli değildir. Herhangi bir isim vererek parametre
geçirebiliriz. Aşağıdaki gibi tanımlama yapabiliriz.
1
//MainParametresi2.java - 05.04.2014
2
3
public class MainParametresi2
4
{
5
public static void main(String[] dizi) // args yerine dizi adı
6
verildi
7
{
8
System.out.println("Main Metodu");
9
}
10
11
}
Peki, bu dizimizin içerisinde hangi elemanlar var? Biz bu parametre
içerisindeki elemanları yazdırmak istersek, ne ile karşılaşacağız?
//MainParametresi2.java - 05.04.2014
1
2
public class MainParametresi2
3
{
4
public static void main(String[] dizi) // args yerine dizi adı
5
verildi
6
{
7
System.out.println(dizi[0]);
8
}
9
}
10
11
Ekran çıktısı:
Exception in thread "main"
1
java.lang.ArrayIndexOutOfBoundsException: 0
2
at MainParametresi2.main(MainParametresi2.java:7)
Bu örnekte String tipindeki dizinin ilk elemanını yazdırmak istiyoruz ve hata
ile karşılaşıyoruz. Yani bu da demek oluyorki; bu dizimizin içerisinde eleman
yok. Bu diziye eleman eklemek için şu adımları takip edelim.
1.
Üstteki menüden Run'a tıklayıp Run Configurations diyoruz.
Karşımıza aşağıdaki gibi bir ekran gelecektir.
2.
Yukarıdaki pencerelerden Arguments'e tıklıyoruz ve Program
Arguments kısmına istediğimiz argümanları yazıyoruz.
3.
Daha sonra Apply diyerek penceremizi kapatıyoruz.
Şimdi ise aşağıdaki programı çalıştırıp çıktısına bakabiliriz.
1
//MainParametresi3.java - 05.04.2014
2
3
public class MainParametresi3
4
{
5
6
7
8
9
10
11
12
13
public static void main(String[] dizi) // args yerine dizi adı
verildi
{
System.out.println(dizi[0]);
System.out.println(dizi[1]);
System.out.println(dizi[2]);
}
}
Ekran çıktısı:
1
Okan
2
Bilke
3
Elektroarge
Argümanları verdikten sonra artık dizimizin elemanlarını ekrana yazdırabiliriz.
Bu argümanlar sadece bu proje için geçerlidir. Argümanları girdiğimiz ekranda
sol tarafta hangi proje üzerinde çalıştığımızı göreceksiniz. Diğer projeler için bu
argümanlar geçerli olmayacaktır. Aşağıdaki resimde görüldüğü yerde hangi
proje üzerinde çalıştığımızı görebilirsiniz.
Yaptığımız bu çalışma, MainParametresi ve MainParametresi2 projesi
üzerinde etki etmeyecektir.
Argümanları girerken bir istisnadan bahsedelim. İsimleri girerken soyadları da
girdiğimizde bir istisna ile karşılaşırız. Soyadlar için boşluk bıraktığımızda
bunlar farklı bir argüman olarak algılanır. Bunu örneğimizde gösterelim.
Girdiğimiz argümanlar aşağıdadır.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//MainParametresi4.java - 05.04.2014
public class MainParametresi4
{
public static void main(String[] dizi) // args yerine dizi adı
verildi
{
System.out.println(dizi[0]);
System.out.println(dizi[1]);
System.out.println(dizi[2]);
System.out.println(dizi[3]);
System.out.println(dizi[4]);
System.out.println(dizi[5]);
System.out.println(dizi[6]);
}
}
Ekran çıktısı:
1
Okan
2
Bilke
3
Onur
4
Bilke
5
Göksu
6
Tuna
7
Elektroarge
Örnekte de gösterdiğimiz gibi boşluktan sonrasını başka bir dizi elemanına
alıyor. Eğer biz bunu bir bütün olarak görsün istiyorsak, ne yapmamız gerekir?
Bunun için tahmin ettiğiniz gibi elemanları tırnak içerisindeyazmamız gerekir.
Hemen eklediğimiz argümanları gösterelim ve çıktımıza bakalım.
Elemanları tırnak içerisinde yazdığımız zaman, bunu bir bütün String olarak
algılıyor ve bunu bir argüman olarak görüyor. Çıktıda bir şeye dikkat
ettiyseniz, 2014 sayısını girdik. Yani verdiğimiz argümanlar int tipinde bile
olsa, onu String'e cast ederek depoluyor.
Istisnalar:
!
main metodu yalnızca String tipinde argüman alabilir.
Bu args adındaki dizinin adının, herhangi bir şey olmasında sakınca
yoktur, hata vermez.
Ders 44 - Arrays Sınıfı Metodları
Arrays sınıfının bazı metotlarını önceki derslerimizde anlatmıştık. Bu
dersimizde Arrays sınıfımızın diğer önemli metodlarını anlatacağız.
ARRAYS.ASLIST METODU İLE DİZİYİ LİSTE YAPISINA
KOPYALAMA
Dizimizin içeriğini Arrays sınıfının asList() metodu yardımıyla bir liste
yapısına aktarabiliriz. Metodumuz parametre olarak bir dizi alır ve geriye
bir liste yapısı verir. Metodumuzu daha iyi anlamak için bir örnek yapalım:
1
//ArraysOrnekleri.java - 05.04.2014
2
3
import java.util.ArrayList;
4
import java.util.Arrays;
5
import java.util.List;
6
7
public class ArraysOrnekleri
8
{
9
public static void main(String[] args)
10
{
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
String dizi[] = {"Edirne", "İstanbul", "Lüleburgaz",
"Tekirdağ"};
Integer dizi1[] = {22, 34, 39, 59};
// dizilerimizi oluşturduk
List ListeYapisi = new ArrayList();
List ListeYapisi1 = new ArrayList();
// liste yapılarımızı oluşturduk
ListeYapisi = Arrays.asList(dizi);
ListeYapisi1 = Arrays.asList(dizi1);
// dizilerimizi asList() metodu ile liste yapısına
dönüştürdük
System.out.println(ListeYapisi.get(1));
System.out.println(ListeYapisi);
System.out.println(ListeYapisi1.get(0));
System.out.println(ListeYapisi1);
}
}
Ekran çıktısı:
1
İstanbul
2
[Edirne, İstanbul, Lüleburgaz, Tekirdağ]
3
22
4
[22, 34, 39, 59]
Yukarıdaki örneğimizde oluşturduğumuz dizilerimizi asList() metodu
yardımıyla liste yapısına kopyalamış olduk. Liste yapımızı ekrana
yazdırdığımızda dizinin elemanlarının sıralı bir biçimde liste yapısına
aktarılmış olduğunu gördük.
ARRAYS.COPYOF METODU İLE DİZİNİN BELLİ BÖLÜMÜNÜ
KOPYALAMA
Dizimizi başka bir diziye kopyalayabileceğimiz bir diğer
metot Arrays sınıfının copyOf() metodudur. Bu metod, özel bir dizi kopyalama
metodudur. Bu metod ile dizimizin belli bir bölümünü başka bir diziye
kopyalayabiliriz. Metodumuz iki parametre alır ve geriye bir dizi döndürür.
Metodumuzun aldığı ilk parametrekopyalanacak dizidir, ikinci parametre ise
diziden kaç eleman kopyalanacağını belirten bir integer değerdir.
Metodumuzu şimdi bir örnek üzerinde deneyerek daha iyi anlamaya çalışalım:
//ArraysOrnekleri2.java - 05.04.2014
1
2
import java.util.Arrays;
3
4
public class ArraysOrnekleri2
5
{
6
public static void main(String[] args)
7
{
8
char dizi[] = {'E', 'l', 'e', 'k', 't', 'r', 'o', 'a', 'r', 'g', 'e'};
9
char yeniDizi[];
10
11
System.out.print("Kopyalanacak dizi: ");
12
for(int j = 0 ; j < dizi.length ; j++)
13
{
14
System.out.print(dizi[j]);
15
}
16
// kaynak dizimizi ekrana yazdırdık
17
18
yeniDizi = Arrays.copyOf(dizi, 3);
19
// kaynak dizimizden belirttiğimiz kadar eleman
20
kopyaladık
21
22
System.out.print("\nOluşan yeni dizi: " );
23
for(int k = 0 ; k < yeniDizi.length ; k++)
24
{
25
System.out.print(yeniDizi[k]);
26
}
27
}
28
}
29
30
Ekran çıktısı:
1
Kopyalanacak dizi: Elektroarge
2
Oluşan yeni dizi: Ele
Yukarıdaki örneğimizde oluşturduğumuz char tipte bir
dizinin copyOf() metodunu kullanarak, üç adet elemanını yeni oluşturduğumuz
diziye kopyaladık.
ARRAYS.COPYOFRANGE İLE İKİ İNDİS ARASINDAKİ
ELEMANLARI KOPYALAMA
Dizimizi başka bir diziye kopyalayabilen özelleşmiş metotlardan birisi
de Arrays sınıfının copyOfRange()metodudur. Bu metodumuz, üç parametre
alır. İlk parametre de kopyalanacak kaynak dizi belirtilir, ikinci parametrede
dizinin hangi elemanından kopyalamaya başlanılacağını belirten bir değer
belirtilir. Son parametrede ise dizinin hangi elemanına kadar kopyalamanın
devam edeceğini gösteren bir değer belirtiriz.
Şimdi metodumuzu örnek üzerinde deneyelim:
//ArraysOrnekleri3.java - 05.04.2014
1
2
import java.util.Arrays;
3
4
public class ArraysOrnekleri3
5
{
6
public static void main(String[] args)
7
{
8
int dizi[] = {14, 53, 19, 23, 20, 12};
9
int yeniDizi[];
10
11
System.out.println("Kopyalanacak dizi: ");
12
for(int j = 0 ; j < dizi.length ; j++)
13
{
14
System.out.print(dizi[j]);
15
}
16
// kaynak dizimizi ekrana yazdırdık.
17
18
yeniDizi = Arrays.copyOfRange(dizi, 2, 6);
19
// kaynak diziden 2 ve 6 indis değerleri arası
20
kopyalandı.
21
22
System.out.println("\nYeni oluşan dizi: ");
23
for(int k = 0 ; k < yeniDizi.length ; k++)
24
{
25
System.out.print(yeniDizi[k]);
26
}
27
// yeni oluşan diziyi ekrana yazdırdık.
28
}
29
}
30
31
Ekran çıktısı:
1
Kopyalanacak dizi:
2
145319232012
3
Yeni oluşan dizi:
4
19232012
Örneğimizde görüldüğü gibi oluşturduğumuz dizinin
elemanlarını copyOfRange() metodu ile ikinci dizimize kopyalamayı başardık.
Örneğe dikkat edersek; bizim dizimizde 6 indis değerli eleman yoktur, ama
dizimizi kopyalarken indis değerimize 6 değerini verdik. Burada verdiğimiz
değerler eleman sırasıdır ve verdiğimiz alt sınır işleme dahil değildir.
Örneğimizde alt verdiğimiz alt sınırın bir fazlasından (3. eleman) başlayarak üst
sınıra kadar olan elemanları kopyaladık.
ARRAYS.FILL METODU İLE DİZİYE ELEMAN ATAMAK
Dizimizin belli bir bölümüne veya tamamına Arrays sınıfının fill() metodu ile
değer atayabiliriz. Bu metod, kendisine verilen değeri dizinin tüm elemanlarına
veya belirttiğimiz indisler arasındaki elemanlara atar. Metodumuzun genel
olarak iki formu vardır. Bunlar şöyledir:
1
fill(Object array[], Object value)
2
fill(Object array[], int baslangic, int bitis, Object value)
Metodumuz ilk formda tüm diziyi, parametre olarak verilen değer ile doldurur.
İkinci form da ise yine parametre olarak verilen değeri, belirttiğimiz indis
değerleri arasındaki bölüme yazar. Metodumuzu örnek üzerinde göstererek
daha iyi anlamaya çalışalım:
1
//ArraysOrnekleri4.java - 05.04.2014
2
3
import java.util.Arrays;
4
5
public class ArraysOrnekleri4
6
{
7
public static void main(String[] args)
8
{
9
int dizi[] = {0, 0, 0, 0, 0};
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int dizi1[] = {1, 1, 1, 1, 1};
Arrays.fill(dizi, 1);
Arrays.fill(dizi1, 2, 4, 0);
// dizilerimize elemanları doldurduk
System.out.println("Eleman doldurduğumuz ilk dizi:
");
for(int j = 0 ; j < dizi.length ; j++)
{
System.out.print(dizi[j]);
}
// ilk dizimizi ekrana yazdırdık.
System.out.println("\nEleman doldurdugumuz ikinci
dizi: ");
for(int k = 0 ; k < dizi1.length ; k++)
{
System.out.print(dizi1[k]);
}
// ikinci dizimizi ekrana yazdırdık
}
}
Ekran çıktısı:
1
Eleman doldurduğumuz ilk dizi:
2
11111
3
Eleman doldurdugumuz ikinci dizi:
4
11001
Yukarıdaki örneğimizde oluşturduğumuz dizilere fill() metodu ile verdiğimiz
değerleri doldurduk. İlk bölümde fill() metodumuzun birinci formunu
kullanarak, bütün diziyi verdiğimiz değer ile doldurduk. İkinci bölümde ise
dizinin 2 - 4 arasındaki bölümüne verdiğimiz değerleri doldurduk.
Ders İçinde Yazılmış Tüm Programlar ve Kodları Ektedir:
Ders 45 - Scanner Sınıfına Giriş
Bir programlama dilinde, kullanıcıdan veri girişi yapmasını isteyebiliriz.
Kullanıcının girdiği bu verilere göre işlem yapabilir, bunları ekrana yazdırabilir
veya herhangi bir yere parametre olarak verebiliriz. Bunu
Java'daScanner sınıfları ile yapıyoruz. Sınıfın ne demek olduğu
konusunda Nesneye Yönelik Programlamaderslerimizde tekrar değineceğiz.
Scanner sınıfı, java.util paketinde yer alır. Scanner sınıflarını kullanabilmek
için java.util.Scanner sınıfını import etmemiz gereklidir. Sadece bu sınıfı değil
de java.util paketindeki tüm sınıfları da import ederek,Scanner sınıfını
kullanabiliriz. Bunun için de java.util.* diyerek bu paketteki sınıfları import
edebiliriz.
Scanner sınıfı ile klavyeden veri okumak için öncelikle bu sınıftan bir nesne
oluşturmak gerekir.
Scanner veriAl = new Scanner(System.in); // veriAl nesnesi
1
oluşturuldu
Scanner sınıfının yapıcısına System.in InputStream kaynağı verilir(Standart
Input Stream - Klavyeden Veri Girişi) Daha sonra oluşturduğumuz
bu veriAl nesnesi üzerinden Scanner sınıfının metodlarına erişeceğiz. Eğer
kullanıcıdan alacağımız veri int tipindeyse bunun için:
1
int sayi = veriAl.nextInt(); // int tipinde bir sayı alır
Bu metod ile kullanıcıdan bir int tipinde sayı girmesi beklenecektir. Kullanıcı
sayıyı girip Enter tuşuna bastığında bu değer alınıp sayi değişkenine
atanacaktır. Eğer kullanıcının gireceği değer int değil de başka bir tipte
olacaksa, bunun için kullanılacak olan metodlar şunlardır:

nextByte(): Klavyeden byte türünde değerler okur.

nextShort(): Klavyeden short türünde değerler okur.

nextFloat(): Klavyeden float türünde değerler okur.

nextDouble(): Klavyeden double türünde değerler okur.

nextBoolean(): Klavyeden mantıksal değerler okur.

nextLine(): Klavyeden String değerler okur. Eğer String içerisinde
boşluk olsa bile cümlenin tamamınıokur.

next(): Klavyeden String değerler okur. Eğer bu String içerisinde
boşluk olursa boşluğa kadar olan kısmı alır. Boşluk
yoksa tamamını bir değişkene atar.
Artık, kullanıcıdan veri girişinin nasıl yapıldığını öğrendikten sonra if
else, switch ve döngüleri kullanarak örnekler verebiliriz.
SCANNER SINIFI İLE İLGİLİ ÖRNEKLER
Scanner sınıfını kullanarak birkaç örnek verelim ve olayı daha iyi kavrayalım:
//ScannerSinifi.java - 05.04.2014
1
2
import java.util.Scanner;
3
4
public class ScannerSinifi
5
{
6
public static void main(String[] args)
7
{
8
System.out.println("3 sayı girin");
9
Scanner veriAl = new Scanner(System.in); // nesne
10
oluşturuldu
11
int veri1 = veriAl.nextInt(); // girilen veriler alınıyor
12
int veri2 = veriAl.nextInt();
13
int veri3 = veriAl.nextInt();
14
System.out.println("Girdiğiniz sayılar:");
15
System.out.println(veri1);
16
System.out.println(veri2);
17
System.out.println(veri3);
18
}
19
}
20
21
Ekran çıktısı:
1
3 sayı girin
2
4
3
1
4
88
5
Girdiğiniz sayılar:
6
4
7
1
8
88
Basit bir örnek ile başladık. Kullanıcıdan sayı alıyoruz ve ekrana yazdırıyoruz.
Başka bir örnek verelim:
1
//ScannerSinifi2.java - 05.04.2014
2
3
import java.util.Scanner;
4
5
public class ScannerSinifi2
6
{
7
public static void main(String[] args)
8
{
9
System.out.println("Bir cümle girin");
10
Scanner veriAl = new Scanner(System.in);
11
for(int a = 0 ; a < 10 ; a++)
12
{
13
String veri1 = veriAl.next();
14
System.out.println(veri1);
15
}
16
}
17
}
18
19
Ekran çıktısı:
1
Bir cümle girin
2
Elektroarge; Elektronik Araştırma Geliştirme Platformu
3
Elektroarge;
4
Elektronik
5
Araştırma
6
Geliştirme
7
Platformu
Bu örnekte kullanıcının klavyeden String tipinde bir cümle girmesini istedik ve
bunu next() metodu ile aldık. Bu metod, boşluğa kadar olan kısmı alıyordu.
Bu metodu her çağırışımızda bize cümleyi kelimeler halinde ayırdı ve biz de
bunları ekrana yazdık. Bu girilen cümlemiz 10 kelimeden fazla olmasın diyerek
döngümüzü 10 kere çalıştırdık. Her seferinde boşluğa kadar olan kısmı aldı.
Şimdiki örneğimizde ise kullanıcıdan farklı tipte veriler alalım:
1
//ScannerSinifi3.java - 05.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Scanner;
public class ScannerSinifi3
{
public static void main(String[] args)
{
Scanner s1 = new Scanner(System.in);
System.out.println("int tipinde bir veri
girin");
int deger1 = s1.nextInt();
System.out.println("String tipinde bir veri
girin");
String deger2 = s1.next();
System.out.println("Boolean tipinde veri
girin");
boolean deger3 = s1.nextBoolean();
System.out.println("Girilen değerler:");
System.out.println(deger1);
System.out.println(deger2);
System.out.println(deger3);
}
}
Ekran çıktısı:
1
int tipinde bir veri girin
2
2014
3
String tipinde bir veri girin
4
Okan
5
Boolean tipinde veri girin
6
false
7
Girilen değerler:
8
2014
9
Okan
10
false
Bu örnekte söylememiz gereken bir şey var. Boolean tipinde değer istendiği
zaman biz bundan başka bir tipte veri girersek, hata verecektir.
Bir başka örnek verelim:
1
//ScannerSinifi4.java - 05.04.2014
2
3
import java.util.Scanner;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ScannerSinifi4
{
public static void main(String[] args)
{
Scanner s1 = new Scanner(System.in);
System.out.println("Notunuzu giriniz");
int not = s1.nextInt(); // not alındı
if(not > 50)
// karşılaştırmalar
yapılıyor
System.out.println("Geçtiniz");
else
System.out.println("Kaldınız");
}
}
Ekran çıktısı:
1
Notunuzu giriniz
2
66
3
Geçtiniz
Bu örneğimizde de girilen nota bakarak geçip geçmediğimizi ekrana yazıyoruz.
Başka bir örnekte, kullanıcıdan alınan 2 değeri kullanarak işlem yapılmasını
görelim:
1
//ScannerSinifi5.java - 05.04.2014
2
3
import java.util.Scanner;
4
5
public class ScannerSinifi5
6
{
7
public static void main(String[] args)
8
{
9
int toplam = 0;
10
Scanner veriAl = new Scanner(System.in);
11
System.out.println("Lütfen ilk tamsayıyı girin:");
12
int sayi1 = veriAl.nextInt(); // başlangıç değeri alındı
13
System.out.println("Lütfen ikinci tamsayıyı girin:");
14
int sayi2 = veriAl.nextInt(); // bitiş değeri alındı
15
for(int a = sayi1 ; a <= sayi2 ; a++)
16
{
17
toplam += a; // başlangıç ve bitiş arasındaki sayılar toplandı
18
19
20
21
22
23
}
System.out.println("İki değer arasındaki sayıların toplamı: " +
toplam);
}
}
Ekran çıktısı:
1
Lütfen ilk tamsayıyı girin:
2
3
3
Lütfen ikinci tamsayıyı girin:
4
7
5
İki değer arasındaki sayıların toplamı: 25
Bu örnekte kullanıcıdan alınan 2 değer arasındaki (bu değerler de dahil) sayılar
toplanarak ekrana yazdırıldı. Eğer bu alınan değerlerin dahil olmasını
istemeseydik, a değerini sayi1 + 1'den başlatırdık ve bitiş değerinde ise a <
sayi2 yapardık.
Scanner sınıfı ile kullanıcıdan değer almaya bir örnek daha verelim.
1
//ScannerSinifi6.java - 05.04.2014
2
3
import java.util.Scanner;
4
5
public class ScannerSinifi6
6
{
7
public static void main(String[] args)
8
{
9
int toplam = 0;
10
Scanner s1 = new Scanner(System.in);
11
while(true) // sonsuz döngü
12
{
13
System.out.println("Değer Giriniz");
14
int a = s1.nextInt();
15
if(a > 0)
16
toplam += a;
17
else
18
break;
19
}
20
System.out.println("Sayıların toplamı: " +
21
toplam);
22
}
23
24
}
Ekran çıktısı:
Değer Giriniz
1
6
2
Değer Giriniz
3
9
4
Değer Giriniz
5
2
6
Değer Giriniz
7
-1
8
Sayıların toplamı:
9
17
Bu örnekte while(true) ile sonsuz döngüye girdik. Her seferinde kullanıcıdan
bir sayı istedik. Eğer bu sayı 0'dan büyükse, girilen her değeri toplayacak. Eğer
0 ve negatif ise döngüden çıkacak ve girilmiş olan tüm sayıların toplamını
ekrana yazacak.
Bir de diziler ile ilgili örnek yapalım:
1
//ScannerSinifi7.java - 05.04.2014
2
3
import java.util.Scanner;
4
5
public class ScannerSinifi7
6
{
7
public static void main(String[] args)
8
{
9
Scanner s = new Scanner(System.in);
10
int dizi[][] = new int[2][2];
11
System.out.println("Dizinin 1. satır 1. sütununu
12
girin:");
13
dizi[0][0] = s.nextInt();
14
System.out.println("Dizinin 1. satır 2. sütununu
15
girin:");
16
dizi[0][1] = s.nextInt();
17
System.out.println("Dizinin 2. satır 1. sütununu
18
girin:");
19
dizi[1][0] = s.nextInt();
20
System.out.println("Dizinin 2. satır 2. sütununu
21
girin:");
22
23
24
25
26
27
28
29
30
dizi[1][1] = s.nextInt();
for(int j = 0 ; j < 2 ; j++)
{
for(int k = 0 ; k < 2 ; k++) // diziyi ekrana
yazdırdık
{
System.out.print(dizi[j][k] + "\t");
}
System.out.println("");
}
}
}
Ekran çıktısı:
Dizinin 1. satır 1. sütununu
girin:
1
6
2
Dizinin 1. satır 2. sütununu
3
girin:
4
1
5
Dizinin 2. satır 1. sütununu
6
girin:
7
88
8
Dizinin 2. satır 2. sütununu
9
girin:
10
-5
6 1
88 -5
Bu örnekte ise 2 boyutlu bir dizi oluşturduk. Kullanıcıdan
aldığımız int tipindeki verileri bu diziye atadık ve daha sonra da bu elemanları
matris şeklinde ekrana yazdırdık.
Bir de sayı tahmin oyunu yapalım:
1
//ScannerSinifi9.java - 05.04.2014
2
3
import java.util.*; // Scanner ve Random sınıflarını
4
import ettik
5
6
public class ScannerSinifi8
7
{
8
public static void main(String[] args)
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
int deger = 1;
Random r = new Random();
int sayi = r.nextInt(10); // rasgele sayı ürettik
Scanner s = new Scanner(System.in);
while(true)
{
System.out.println("Tahmin Girin (0-10):");
int tahmin = s.nextInt(); // tahmin alınıyor
if (tahmin == sayi)
// tahmin sayıya eşit mi?
{
System.out.println(deger + ". tahminde
bildiniz");
break;
}
else
deger += 1; // her tahminde bunu artırdık
}
}
}
Ekran çıktısı:
1
Tahmin Girin (0-10):
2
3
3
Tahmin Girin (0-10):
4
5
5
Tahmin Girin (0-10):
6
7
7
Tahmin Girin (0-10):
8
8
9
Tahmin Girin (0-10):
10
4
11
5. tahminde bildiniz
Yine bu örnekte sonsuz döngüye girdik ve tahmini bulduğumuz anda döngüden
çıktık. Her tahminde detahmin sayısını 1 artırdık ve sonunda kaçıncı
tahminde sayının bulunduğunu yazdık. Random sınıfını kullanarak programın
başında bir rastgele değer üretmiştik bu değeri bulmaya çalıştık.
Ders 46 - JOptionPane Kullanımı
JOptionPane, Java'ya yeni başlayanların adını ilk defa duydukları bir kavram
olabilir. JOptionPane, kullanıcı ile iletişimi sağlar. Yani kullanıcıdan veri
alır veya kullanıcıya bir mesaj gösterir. Bu veri alıp gösterme işlemini, bir
pencere yardımıyla yapar. Konsol uygulamalarının yerine form uygulaması
özelliği getirmiştir.
Bunu kullanabilmek için ilk
olarak javax.swing.JOptionPane sınıfını import etmemiz gerekir.
Şimdi ilk olarak kullanıcıdan veri almayı görelim.
KULLANICIDAN VERİ ALMA
JOptionPane ile kullanıcıdan bir pencere yardımıyla veri almak için
kullanacağımız metod:
1
JOptionPane.showInputDialog(Buraya mesaj yazılacak);
Şimdi basit bir örnek ile başlayalım:
//JOptionPaneKullanimi.java - 05.04.2014
1
2
import javax.swing.JOptionPane; // import ettik
3
4
public class JOptionPaneKullanimi
5
{
6
public static void main(String[] args)
7
{
8
String sayi = JOptionPane.showInputDialog("Bir sayı
9
girin");
10
}
11
}
12
13
Ekran çıktısı:
Şekilde görüldüğü gibi bir pencere açılıyor ve kullanıcıdan veri girişi yapılması
isteniyor. Hemen burada bir not düşelim.
Istisnalar:
!
JOptionPane ile kullanıcıdan veri istendiğinde, girilen
değer String tipindedir.
Notumuzda anlattığımız gibi örnek üzerinde de doğrudan String tipindeki bir
değişkene attık. Peki, bu girilen sayı üzerinde matematiksel işlem yapmak
istiyorsak ne yapacağız?
Bunu önceki konulardan biliyoruz artık. Değişken üzerinde casting işlemi
yapacağız. Hemen buna da bir basit örnek verelim:
//JOptionPaneKullanimi2.java - 05.04.2014
1
2
import javax.swing.JOptionPane;
3
4
public class JOptionPaneKullanimi2
5
{
6
public static void main(String[] args)
7
{
8
String sayi = JOptionPane.showInputDialog("Bir sayı
9
girin");
10
int yeniSayi = Integer.parseInt(sayi); // cast işlemi
11
}
12
}
13
14
Bu şekilde yaparak alınan bir sayıyı int'e cast edebiliriz.
Artık yeniSayi değişkenimizi matematiksel işlemlerde kullanabiliriz.
BİLGİ MESAJI GÖSTERME
Bir pencere yardımıyla kullanıcıya mesaj göstermek isteyebiliriz. Bu mesaj,
doğrudan bir String ya da buString verinin yanında değişkenlerin de yazılmış
bir şekli olabilir.
İlk olarak mesaj göstermek için kullanacağımız metodu verelim.
1
JOptionPane.showMessageDialog(null, mesajımız);
Yukarıdaki metodu kullanarak kullanıcıya bilgilendirme mesajı yazabiliriz. Bu
metodun ilk parametresinull'dur. Diğer parametresi ise, vermek istediğimiz
mesajdır.
Şimdi basit bir örnekle başlayalım:
//JOptionPaneKullanimi3.java - 05.04.2014
1
2
import javax.swing.JOptionPane;
3
4
public class JOptionPaneKullanimi3
5
{
6
public static void main(String[] args)
7
{
8
JOptionPane.showMessageDialog(null, "Bilgilendirme
9
Mesajı");
10
}
11
}
12
13
Ekran çıktısı:
Bu metodumuz 2 parametrenin yanında 4 parametre de alabilir.
Parametrelerden birisi, çıkan pencereninbaşlığıdır. Diğer parametre ise
pencerede ise pencerede çıkan bilgilendirme resmidir. Şimdi bu parametreleri
kullanarak başka bir örnek yapalım:
//JOptionPaneKullanimi4.java - 05.04.2014
1
2
import javax.swing.JOptionPane;
3
4
public class JOptionPaneKullanimi4
5
{
6
public static void main(String[] args)
7
{
8
JOptionPane.showMessageDialog(null, "Bilgilendirme Mesajı",
9
"Sonuç", JOptionPane.OK_OPTION);
10
}
11
}
12
13
Ekran çıktısı:
Burada Sonuç adındaki parametremiz, penceremizin başlığını oluşturur. Son
parametre ise, sol tarafta bulunan ikondur. Bu resmi değiştirebiliriz. En sonda
bulunan parametreyi değiştirdiğimizde ikon da değişir. Bu parametrelerin sırası
değiştirilemez.
Şimdi soldaki ikonu değiştirdiğimiz farklı bir örnek verelim:
1
//JOptionPaneKullanimi5.java - 05.04.2014
2
3
import javax.swing.JOptionPane;
4
5
public class JOptionPaneKullanimi5
6
{
7
public static void main(String[] args)
8
{
9
int a = 5;
10
11
12
13
14
JOptionPane.showMessageDialog(null, a,
"Sonuç", JOptionPane.WARNING_MESSAGE);
}
}
Ekran çıktısı:
Bu örnekte de 2. parametremiz mesajımız olduğu için biz
mesajımızı int tipindeki bir değişken olarak verdik. Herhangi bir String olarak
da verebilirdik. 3. parametre yine pencere adı oldu. Son parametre ise, bu sefer
başka bir mesaj ikonu olarak belirlendi. Duruma göre bunu değiştirebiliriz.
Aşağıdaki listeye baktığımızda kullanabileceğimiz mesaj resimlerini görebiliriz.
Yukarıdaki gibi klavyede . (nokta) tuşuna bastığımızda, kullanabileceğimiz
şekillerin adları çıkmaktadır.
JOPTIONPANE İLE İLGİLİ ÖRNEKLER
Şimdi anlattığımız bu 2 özellik(veri alma ve gösterme) ile ilgili örnekler
verelim:
//JOptionPaneKullanimi6.java - 05.04.2014
1
2
import javax.swing.JOptionPane;
3
import java.util.Random;
4
5
public class JOptionPaneKullanimi6
6
{
7
public static void main(String[] args)
8
{
9
int i = 1;
10
Random r = new Random();
11
int sayi = r.nextInt(10); // bilinecek olan sayı belirlendi
12
while(true) // sonsuz döngü kuruldu
13
{
14
String tahmin = JOptionPane.showInputDialog("Tahmin
15
Gir:");
16
int t = Integer.parseInt(tahmin);
17
if(t == sayi) // tahmin ile sayı tutuyorsa
18
{
19
String mesaj = "Tahmin doğru! - " + i + ". tahminde
20
bildiniz";
21
JOptionPane.showMessageDialog(null, mesaj);
22
break;
23
}
24
else
25
i++; // tutmuyorsa sayacı artır, başa dön
26
}
27
}
28
}
29
Ekran çıktısı:
Örneğimizde ilk olarak Random sınıfı ile 0 - 10 arasında rastgele bir sayı
belirledik. Daha sonra tahminler ile bunu bulmaya çalıştık. Bulduğumuz zaman
kaçıncı tahminde bulduğumuzu gösteren bir kontrol koyduk. Eğer tahmin yanlış
ise, sadece sayacı artırdık. Doğru bildiğimizde break; ile sonsuz döngüyü
sonlandırarak çıktık.
Başka bir örnek yapalım:
1
//JOptionPaneKullanimi7.java - 05.04.2014
2
3
import javax.swing.JOptionPane;
4
5
public class JOptionPaneKullanimi7
6
{
7
public static void main(String[] args)
8
{
9
String sayi1 = JOptionPane.showInputDialog("İlk sayıyı girin");
10
int a = Integer.parseInt(sayi1);
11
String sayi2 = JOptionPane.showInputDialog("İkinci sayıyı girin");
12
int b = Integer.parseInt(sayi2);
13
int sonuc = hesapla(a, b);
14
JOptionPane.showMessageDialog(null, sonuc, "Toplam",
15
JOptionPane.PLAIN_MESSAGE);
16
}
17
18
19
20
21
22
23
24
25
26
27
28
static int hesapla(int a, int b)
{
int toplam = 0;
for(int i = a ; i <= b ; i++)
{
toplam += i;
}
return toplam;
}
}
Ekran çıktısı:
Bu örnekte kullanıcıdan aldığımız 2 sayı ile işlem yapılmaktadır. Alınan 2 sayı
arasındaki değerleri toplar ve ekranda bilgi mesajı olarak verir. Alınan
değerleri hesapla() adlı metoda gönderiyor ve sonucu, pencereye bir parametre
olarak veriyor.
Şimdi de son olarak klasik bir örnek olan vize ve final notu alıp ortalama bulan
bir program yapalım ve sonuçlarına bakalım:
1
//JOptionPaneKullanimi8.java - 05.04.2014
2
3
import javax.swing.JOptionPane;
4
5
public class JOptionPaneKullanimi8
6
{
7
public static void main(String[] args)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
String vize = JOptionPane.showInputDialog("Vize notunu giriniz");
int v1 = Integer.parseInt(vize);
while(v1 < 0 || v1 > 100)
{
vize = JOptionPane.showInputDialog("Vize notunu tekrar
giriniz");
v1 = Integer.parseInt(vize);
}
String finalNotu = JOptionPane.showInputDialog("Final notunu
giriniz");
int f1 = Integer.parseInt(finalNotu);
while(f1 < 0 || f1 > 100)
{
finalNotu = JOptionPane.showInputDialog("Final notunu tekrar
giriniz");
f1 = Integer.parseInt(finalNotu);
}
int not = (int)(v1 * 0.3 + f1 * 0.7);
String sonuc = "Notunuz: " + not;
JOptionPane.showMessageDialog(null, sonuc, "Not Açıklama",
JOptionPane.INFORMATION_MESSAGE);
}
}
Ekran çıktısı:
Bu örnekte, girilen vize notu 0'dan küçük veya 100'den büyükse, tekrar vize
notunu istiyor. Bu işlem, 0 - 100 arasında değer girilene kadar devam ediyor.
Aynı şekilde final notu için de bu şekilde yapılıyor. Finalnotunu değişkene
atarken final yazdığımızda hata verir çünkü bu Java'nın kendisine ait anahtar
kelimelerinden birisidir. Biz de bunu finalNotu olarak değiştirdik. Bu tür
anahtar kelimelerin değişken ismi olarak kullanılmadığını görmüştük diğer
anahtar kelimelere [url=Ders 16 - Java'da Kullanılan Anahtar
Kelimeler]http://www.elektroarge.com/java/ders-16-java-da-kullanilan-anahtarkelimeler-t704.html[/url] dersinden ulaşabilirsiniz. Biz de
bunu finalNotu olarak değiştirdik. Bu tür anahtar kelimelerin değişken ismi
olarak kullanılamadığını hatırlayalım.
Daha sonra notların ortalamasını alıyor ve pencerede gösteriyor. Girilen notları,
üzerinde işlem yapabilmek için int tipindeki değişkene cast ettik.
Son olarak sonuc değişkenine, String ve int tipindeki değişkeni birleştirerek
atama yapıyoruz. Bunu, pencere notumuzu gösterdiğimizde daha açıklayıcı
olması için yaptık.
Ders 47 - Nesneye Yönelik Programlamaya Giriş
Nesneye yönelik programlama, yazılım karmaşıklığını ortadan kaldırmak
amacıyla 1960'lı yılların sonunda ortaya çıkan bir yaklaşımdır. Yazılımdaki
karmaşıklıktan kastımız şudur. Nesneye yönelik programlama sayesinde,
yazdığımız programların daha rahat kontrol edilmesi sağlandı. Oluşan herhangi
bir hata, program parçalara bölündüğü için daha rahat bulunur hale geldi.
Bölünen bu parçaların organize bir şekilde çalışması sağlanarak, daha gelişmiş
programlar yazılabilir hale geldi ve bunun yanında performans artışı sağlandı.
Nesneye yönelik programlamanın sağladığı avantajlar, onu günümüzde geniş
çaplı projeler için vazgeçilmez yapmıştır.
Yazılımdaki karışıklığa çözüm için kullanılan prensipler vardır.
Bunlar; kalıtım (inheritance), çok
biçimlilik(polymorphism), soyutlama (abstraction), sarmalama (encapsulatio
n) gibi kavramlardır. Bunları ileriki derslerimizde göreceğiz.
Aslında nesneye yönelik programlamanın temelinde hiyerarşi yatar. Bu
hiyerarşiyi de sınıflar venesneler oluşturur. Mesela; bir işyeri düşünelim. Bu
nesneye yönelik programlama mantığında sınıfa karşılık gelir. Bu iş yerindeki
her bir çalışan ise nesneye karşılık gelir. İşyerindeki her bir çalışanın, yani
nesnenin diğer nesneler ile etkileşmesi ve organize çalışması sonucunda
nesneye yönelik programlama kavramı ortaya çıkmıştır. Sınıf ve nesne
kavramlarını daha yakından ve detaylı inceleyelim.
Ders 48 - Sınıf ve Nesne Kavramları
Nesne kavramının en kısa açıklaması şudur. Doğada herşey bir nesnedir. Uçan
kuş, evimizdeki kapı, pencere, dışarıdaki arabalar vx. Bu nesnelerin iki özelliği
vardır. Bu nesnelerin iki özelliği vardır. Durum vedavranış. Peki, bununla ne
demek istiyoruz?
Örnek olarak bir arabayı düşünelim. Bu arabanın rengi, fiyatı, markası, modeli
gibi özellikleri onundurumunu belirtir. Buna attribute (özellik) de denir. Bu
arabanın hızlanması, yavaşlaması, kaza yapması, vites değiştirmesi gibi
özellikleri ise onun davranışını belirtir. Dolayısıyla durumu ve davranışı olan
herşey birnesnedir. Doğadaki bu araba örneğinin bilgisayar yazılımlarındaki
karşılığı nesnedir. Arabamızın durumundabelirtilen özellikler, nesneye
yönelik programlamada değişkenler üzerinde saklanır. Davranışların nesneye
yönelik programlama karşılığı ise metodlardır. Metodlar, bir çeşit nesne
fonksiyonudur.
Nesne kavramını artık biliyoruz. Şimdi ise sınıfların ne demek olduğunu
anlatalım.
Sınıflar, tahmin ettiğiniz üzere, nesnelerden oluşur.
Nesnelerin durum ve davranışlarını tutar. Örnek olarak bir insan nesnesi
düşünelim. İnsan nesnesinin durumu olan boy, kilo ve davranışı olan nefes alıp
verme gibi özellikleri ile beraber tutulduğu yer sınıftır. Bu insan nesnesinin
sınıfına canlı sınıfı diyebiliriz. Daha sonra bu canlı sınıfından istediğimiz
kadar insan nesnesi oluşturabiliriz. Bu yeni oluşturulan
nesnelere instance(örnek) denir. Bu oluşturduğumuz yeni insanın da nefes
alma, cinsiyet, boy, kilo gibi özellikleri vardır. Bunu, savaş oyunlarındaki
askerlere benzetebiliriz. Her asker bir instance'dir ve her askerin belirli
özellikleri vardır. Dolayısıyla her nesnenin bir sınıfı vardır diyebiliriz.
Bu anlattıklarımızdan yola çıkarak birer taslak, nesnelerin ise bu taslaktan
üretilen birer varlık olduğunu düşünebiliriz. Bu taslakta, nesnelerde olması
gereken özellikler bulundurulur. Bu özellikler hayata geçirilerek bir örnek
oluşturulduğunda ise buna nesne denir. Dolayısıyla bu taslaktan istediğimiz
kadar nesneoluşturabiliriz. Sadece aynı sınıftan türetilen
nesnelerin tipi aynıdır. Yani bir araba sınıfıyla, insan sınıfından türetilen
nesnelerin özellikleri farklıdır.
Şimdi bir insan sınıfı düşünelim. Bu insan sınıfından türetilen nesnelerde boy,
kilo, yaş gibi özellikler mutlaka olacaktır. Bu nesneye yönelik programlamanın
kuralıdır. Fakat burada türetilen her nesnemizde ortak olarak bulunması gereken
özelliklerin değeri farklıdır. Bazı insanlar zayıf, bazı insanlar şişman olabilir.
Nesneye yönelik programlamanın temeli, işte buradan başlamaktadır.
Buraya kadar anlattığımız durum ve davranışlara, nesneye yönelik
programlamada field (alan) denilmektedir.
SINIF OLUŞTURMA
Nesne - sınıf ilişkisini ve bunlara bağlı olarak ortaya çıkan kavramları
gördükten sonra sınıfların ve nesnelerin Java'da nasıl oluşturulduklarına
bakalım.
Java'da sınıf oluşturmak için kullanılan genel format şu şekildedir;
erisim_belirleyici class
1
sinif_ismi
2
{
3
// özellikler
4
// metodlar
5
// yapıcılar
6
}
Burada class sözcüğünün başına erişim belirleyicilerden birisi getirilir.
Bu zorunlu değildir. Erişim belirleyicileri ileriki derslermizde detaylı olarak
göreceğiz. Class sözcüğünden sonra da sınıfımızın ismi yazılır. Daha sonra
açılan süslü parantezler içerisine de durum ve davranışları belirten alanlar
yazılır. Yapıcılar konusunu da ilerleyen sayfalarda anlatacağız.
Basit olarak bir sınıf oluşturma aşağıdaki gibi yapılır.
//Insan.java - 05.04.2014
1
2
public class Insan // Insan adında sınıf
3
oluşturuldu
4
{
5
double boy; // Özellikler tanımlandı (3
6
Özellik)
7
String cinsiyet;
8
int yas;
9
}
10
Yukarıda Insan adında bir class (sınıf) oluşturduk. Sınıfımızın
içerisine boy, yaş, cinsiyet gibi değişkenler koyduk. Görüldüğü gibi bu
değişkenleri şimdilik durum (özellik) olarak belirledik. Bunlar
sadece değişkengörevindedirler. Daha sonra bu sınıfımıza davranış
belirten metodlar da ekleyeceğiz. Davranış derken
meselanefesAl, yuru, kos gibi metodlardan bahsediyoruz.
NEW ANAHTAR KELİMESİ İLE NESNE OLUŞTURMA
Yukarıdaki sınıfımızdan oluşturduğumuz her örneğe nesne denir. Sınıfımızdaki
tüm alanlara, nesnemiz de sahip olur. Diyelim ki bu sınıftan 10
adet insan oluşturduk. Oluşturduğumuz her insan nesnemizin de boyu, yaşı
farklı olabilir.
Java'da bir sınıftan nesne oluşturmak için new anahtar kelimesi kullanılır.
1
Insan okan = new Insan();
Burada insan sınıfından okan adında bir nesne türettik. Bunu new anahtar
sözcüğü ile yapıyoruz.
Oluşturduğumuz okan nesnesi, boy, cinsiyet, yas alanlarına sahip olacaktır. Bir
de onur adında bir nesne oluştursaydık, bu nesnemiz de aynı alanlara sahip
olacaktı.
Şimdi ise bu sınıfımızdan bir nesne oluşturalım ve bu nesnelere değer atayalım.
//Insan.java - 05.04.2014
1
2
public class Insan // Insan adında sınıf oluşturuldu
3
{
4
double boy; // Özellikler tanımlandı (3 Özellik)
5
String cinsiyet;
6
int yas;
7
8
public static void main(String[] args)
9
{
10
Insan kisi = new Insan();
// Insan sınıfından kisi adında bir nesne
11
oluşturuldu
12
kisi.boy = 1.78;
// nesnenin boy değişkenine değer atandı
13
System.out.println(kisi.boy); // nesnemizin boy değeri ekrana yazdırıldı
14
}
15
}
16
17
Ekran çıktısı:
1
1.78
Burada ilk olarak Insan adında bir sınıf oluşturduk ve bu sınıfın alanlarını
belirledik. Bunlar boy, cinsiyetve yas olsun. Daha sonra programımızın
başladığı main metodunu yazdık. Bu metod içerisinde ilk olarak sınıfımızdan
bir nesne oluşturduk. Bunu new anahtar sözcüğü ile yaptık. Oluşturduğumuz
nesnenin adı kisiolsun. Bu nesne, oluşturulduğu sınıftaki tüm özelliklere sahip
olur. Bu kisi nesnesinin boy özelliğine bir değer atadık ve ekrana yazdırdık.
Insan sınıfımızdan oluşturduğumuz bir nesne, o sınıftaki alanlara sahiptir
demiştik. Oluşturulan bu nesnenin özelliklerine nokta (.) ile erişiyoruz.
Yani kisi.boy, kisi.yas diyerek, o kişinin özelliğine değer atayıp ekrana
yazdırabiliriz.
Nokta (.) operatöründen biraz bahsedelim. Bu operatör ile bir sınıfın altında
bulunan metodlara ve değişkenlere erişebiliriz. Yalnızca sınıflarda değil, paket
adlarında da kullanılır. Bu operatör, aslında bir nevihiyerarşi sağlar.
Şimdi ise nesnenin durum özelliğinin yanında davranış özelliğine de bir örnek
verelim. Davranıştan kastımız metodlardır.
1
//Araba.java - 05.04.2014
2
3
public class Araba
4
{
5
String marka, renk; // durum
6
7
void gaza_bas()
// davranış
8
{
9
System.out.println("Araba hızlanıyor");
10
}
11
12
void frene_bas() // davranış
13
{
14
System.out.println("Araba yavaşlıyor");
15
}
16
17
public static void main(String[] args)
18
{
19
Araba a1 = new Araba(); // Araba sınıfından a1 adında nesne
oluşturuldu
a1.marka = "xxx";
// nesnenin markası belirlendi
a1.renk = "siyah";
// nesnenin rengi belirlendi
a1.gaza_bas();
// a1 nesnesinin gazaBas adlı metodu
çalıştırıldı
a1.frene_bas();
// a1 nesnesinin freneBas adlı metodu
çalıştırıldı
}
}
20
21
22
23
24
25
26
27
Ekran çıktısı:
1
Araba hızlanıyor
2
Araba yavaşlıyor
Bu örneğimizde, Araba sınıfından bir nesne oluşturduk ve bu nesne
ile gazaBas ve freneBas metodlarını çağırdık. Bu metodlar, durum
değil davranış özelliği gösterirler. Diğer, marka ve renk
field'ları, durumniteliğindedirler. Türetilen bu nesneye
önce mark ve renk değerleri atanıyor. Daha
sonra gazaBas vefreneBas metodları çağırılıyor.
Istisnalar:
!
Oluşturulan her nesne, bellekte farklı bir alanda tutulur. Nesnelerin
bellekte tutulduğu bölge heap alanıdır. Bu nesnelere, o
nesnenin referansı ile erişebiliriz. Bir nesnenin birden fazla referansı
olabilir.
Bir sınıf içerisinde değişkenlerin, metodların, yapıcıların tanımlanabileceğini
söylemiştik. Değişkenlerin tanımlamasını ve kullanılmasını önceki örneklerde
anlattık. Şimdi daha detaylı bir örnek üzerinde inceleyelim.
1
//Metodlar.java - 05.04.2014
2
3
public class Metodlar // Insan adında sınıf oluşturuldu
4
{
5
int carp(int sayi1, int sayi2)
6
{
7
return sayi1 * sayi2;
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
}
int topla(int sayi1, int sayi2)
{
return sayi1 + sayi2;
}
public static void main(String[] args)
{
Metodlar islem1 = new Metodlar(); // islem1
nesnesi
Metodlar islem2 = new Metodlar(); // islem2
nesnesi
int sonuc = islem1.carp(5,4);
int sonuc2 = islem2.topla(7, 1);
System.out.println("Çarpma sonucu: " + sonuc);
System.out.println("Toplama sonucu: " +
sonuc2);
}
}
Ekran çıktısı:
1
Çarpma sonucu: 20
2
Toplama sonucu: 8
1.
Bu örneğimizde iki tane metod oluşturduk. Birisi aldığı iki
sayıyı çarpıyor, diğeri ise iki sayıyı topluyor. Metodlara nasıl
parametre aktarıldığını Ders 31 - Parametreli Metodlar dersimizde
anlatmıştık.
2.
main metodunun içerisinde Metodlar sınıfından 2 adet nesne
tanımlıyoruz. Dolayısıyla bu nesneler, sınıfın sahip olduğu metodlara
sahip oluyor.
3.
İlk oluşturduğumuz nesnenin carp metodunu çalıştırıyoruz ve değer
olarak 5 ve 4 sayılarını gönderiyoruz. Buradan dönen
değeri sonuc değişkenine atıyoruz.
4.
Daha sonra ikinci nesnemiz üzerinden de topla metodunu çağırıyoruz
ve parametre olarak 7 ve 1 sayılarını gönderiyoruz. Buradan dönen
değeri de sonuc2 değişkenine atıyoruz ve sonuçları ekrana
yazdırıyoruz.
Istisnalar:
!
Bir sınıf içerisinde istediğimiz kadar metod tanımlayabiliriz ve
bunlara istediğimiz kadar parametre gönderebiliriz.
Bu dersteki metodlar kavramında sıkıntı yaşıyorsanız, Metodlar konulu
derslerimize tekrar göz atmanızı öneririz.
Ders 49 - Sınıf ve Nesne Değişkenleri
Java'da nesneye programlama kullandığımız için değişkenler, kullanıldığı yere
göre farklı şekilde adlandırılırlar ve farklı şekilde adlandırılır ve farklı davranış
sergilerler.
Nesneye yönelik programlamada ihtiyaca göre nesne oluştururuz ve her
nesnenin kendine has özellikleri olur. Bu şekilde her nesnenin kendine ait olan
değişkenlerine nesne değişkenleri denir. Bir de her nesne için ortak olarak
kullanılan değişkenler vardır. Bunlar nesneden nesneye farklılık göstermezler.
Bunlara da sınıf değişkenleri denir.
Şimdi örnek üzerinde sınıf değişkenlerini anlatalım.
1
//Degiskenler.java - 05.04.2014
2
3
public class Degiskenler
4
{
5
static int deger = 5; // sınıf
6
değişkeni
7
8
public static void main(String[]
9
args)
10
{
11
Degiskenler d1 = new
12
Degiskenler();
13
14
15
16
Degiskenler d2 = new
Degiskenler();
System.out.println(d1.deger);
System.out.println(d2.deger);
}
}
Ekran çıktısı:
1
5
2
5
Bu örnekte bir tane deger adında sınıf değişkeni tanımladık. Dediğimiz gibi
sınıf değişkenleri, her nesne için ortak kullanılır ve her nesne
için aynıdır. main metodu içerisinde iki tane nesne oluşturduk. Programımız
ilk olarak main çalışmaya başladığı için buradaki nesnelerimizin işlemleri
yapılacaktır. Daha sonra bu iki nesne için de deger değişkenin değeri yazdırıldı.
Bu iki nesne için de bu değişkenin değerinin değerinin 5 olduğu görüldü.
Örnekte de gördüğümüz üzere sınıf değişkenlerini static anahtar kelimesi ile
tanımlıyoruz. static anahtar kelimesini önceki derslerimizde anlatmıştık.

Ders 35 - Static Metodlar

Ders 16 - Java'da Kullanılan Anahtar Kelimeler
Şimdi ise nesne değişkenlerine örnek verelim ve farkı anlayalım.
1
//Degiskenler2.java - 05.04.2014
2
3
public class Degiskenler2
4
{
5
int deger; // nesne değişkeni
6
7
public static void main(String[] args)
8
{
9
Degiskenler2 d1 = new
10
Degiskenler2();
11
Degiskenler2 d2 = new
12
Degiskenler2();
13
d1.deger = 7;
14
d2.deger = 9;
15
16
17
18
System.out.println(d1.deger);
System.out.println(d2.deger);
}
}
Ekran çıktısı:
1
7
2
9
Bu örnekte de iki tane nesne oluşturduk. Bu nesneler Degiskenler2 sınıfına ait.
Daha sonra nesnelerindeger adlı değişkenlerine ayrı ayrı 7 ve 9 değerlerini
atadık. Son olarak da bunları ekrana yazdırdık ve gördük ki her nesne için bu
değişken farklı değerler aldı.
Nesne değişkenlerini normal olarak tanımlıyoruz. Başına erişim belirleyici
getirmezsek, bu public olarak derleyici tarafından belirleniyor. Peki, bu nesne
değişkenini static olarak tanımlasaydık, yani sınıf değişkeniyapsaydık ne
olacaktı? Şimdi ise bunu gösterelim.
//Degiskenler3.java - 05.04.2014
1
2
public class Degiskenler3
3
{
4
static int deger; // sınıf değişkeni
5
6
public static void main(String[] args)
7
{
8
Degiskenler3 d1 = new
9
Degiskenler3();
10
Degiskenler3 d2 = new
11
Degiskenler3();
12
d1.deger = 7;
13
d2.deger = 9;
14
System.out.println(d1.deger);
15
System.out.println(d2.deger);
16
}
17
}
18
Ekran çıktısı:
1
9
2
9
Burada main metodumuzda d1 nesnesi için deger değişkenine 7 değerini
atadık. Değişkenimiz 7 oldu. Şimdi ise d2 nesnesi için de bir değer belirledik.
Normalde her iki nesne için de bu değer farklı olmalı. Fakat
değişkenimiz sınıf değişkeni olduğu için d2 nesnesi için de 9 atadıktan
sonra, deger değişkenimiz artık 9 oldu. Yani bu her nesne için artık 9 değerini
alacak. Dolayısıyla bu değişkenleri ekrana yazdırdığımızda, son atadığımız
değer olan 9 değerini, her iki nesne için de aynı olarak yazdıracak.
Istisnalar:
!
Nesne değişkenleri dinamik değişkenler, yani instance
variable olarak da adlandırılırlar. Sınıf değişkenleri ise static
değişkenler olarak adlandırılırlar.
Istisnalar:
!
Eğer nesne değişkeni tanımladıysak oluşturulan her nesne
için bellekte bir yer ayrılır. Bu nesne değişkenlerinin değeri,
programın herhangi bir yerinde değiştirilebilir. Sınıf değişkenleri için
bellekte sadece biryer ayrılır.
Istisnalar:
!
Sınıf değişkenleri static olarak tanımlandığı için bu değişkenlere
nesne oluşturmadan da sadece sınıf adını kullanarak erişebiliriz. Yani
bunlar nesneden bağımsızdırlar.
Sınıf değişkenleri aynı zamanda static değişkenler olarak adlandırılırlar.
Dediğimiz gibi bu değişkenleresınıf adı ile de erişebiliriz, çünkü
nesneden bağımsızdırlar. Bunun sebebi ise; her nesne için aynı olmasıdır.
Sınıf değişkenleri, diğer bazı dillerdeki global değişken kavramına benzer.
Şimdi ise static, yani sınıf değişkenlerine, sınıf adı ile erişmeye bir örnek
verelim.
//Degiskenler4.java - 05.04.2014
1
2
public class Degiskenler4
3
{
4
static String yazi = "Okan Bilke";
5
6
public static void main(String[] args)
7
{
8
System.out.println(Degiskenler4.yazi); // sınıf adı ile
9
erişildi
10
}
11
}
12
13
Ekran çıktısı:
1
Okan Bilke
Gördüğümüz gibi static olan değişkenlere sadece sınıf adı ile erişebiliyoruz.
Aynı şekilde sınıf adını kullanarak değer de atayabiliriz. Eğer
değişkenimiz static olmasaydı, yani nesne değişkeni olsaydı bu şekilde
erişemeyecektik. Erişmek için bir nesne oluşturmamız gerekecekti.
Örneğimizde bir nesne oluşturmadık.
Bu değişkenler için söyleceğimiz son özellik ise şudur: Sınıf
değişkenleri program bittiğinde bellektensilinirler ve her program için
yalnızca bir defa oluşturulurlar. Nesne değişkenleri ise, nesne yok
olduğundabellekten silinirler.
Ders 50 - Pass By Value - Pass By Reference
PASS BY VALUE - PASS BY REFERENCE (DEĞER VE REFERANS
TİPLER)
Değişkenler konusunu anlatırken Primitive ve Referans tiplere değinmiştik.

Ders 10 - Primitif Tipler

Ders 11 - Referans Tipler
Bu tiplerde bilmemiz gereken bir nokta var.
Bir metoda parametre gönderdiğimizi varsayalım. Metod, bu parametreyi 10 ile
çarpıyor ve ekrana bir şeyler yazıyor. Peki, metoddan çıktığımızda sizce asıl
değişkenimizin değeri de değişiyor mu?
Primitive ve Referans tipler için cevap farklıdır. Primitive (int, double, byte...)
tiplerde, o değeri metoda parametre olarak gönderdiğimizde,
değerin kopyası gönderilir ve orjinal değeri bozulmaz. Referans tiplerde ise
metoda değerin kendisi gönderilir. Metodda olan değişiklikler, değişkenimize
de yansır. Bu konu Değer veReferans tipler olarak bilinir.
Referans tipler ile işlem yaparken nesne ve nesne değişkenlerini kullandığımız
için, bu konuyu Metodlardersinde değil de burada incelemeyi uygun gördük.
Fakat genel olarak bu konu, Metodlar konusunda geçer.
Primitif tiplere bir örnek verelim ve değişkenin orjinal değerinin değişmediğini
görelim.
//Tipler.java - 05.04.2014
1
2
public class Tipler
3
{
4
public static void main(String[] args)
5
{
6
int a = 5;
7
System.out.println("Eski değer: " +
8
a);
9
degistir(a);
10
System.out.println("Yeni değer: "
11
+ a);
12
}
13
static void degistir(int a)
14
{
15
a = a + 10;
16
}
17
}
18
Ekran çıktısı:
1
2
Eski değer: 5
Yeni değer: 5
Bu ilk örneğimizde a değişkenimizi ilk olarak ekrana yazdırdık. Daha sonra
metoda parametre olarak gönderdik. Metodda bu değeri 10 ile topladık.
Metoddan çıktığımızda yeni a değerini ekrana yazdırdık ve gördük ki asıl
değerimizde bir değişiklik olmamış. Çünkü metoda parametre olarak gönderilen
değer, değişkenimizin bir kopyasıdır.
Primitive tiplerde nu böyledir. Bir metoda, değişkenin
değerinin kopyaları gönderilir.
Şimdi de referans tiplere örnek verelim. Referans tipler, new anahtar sözcüğü
ile oluşturuluyorlardı. Metodlara, parametre olarak nesnenin adresi gönderilir.
Bellekte aynı yeri işaret ettikleri için orjinal değeri değişir. Ayrıca istisna
olarak diziler de referans tiplerden sayılırlar.
//Tipler2.java - 05.04.2014
1
2
public class Tipler2
3
{
4
int x;
5
public static void main(String[] args)
6
{
7
Tipler2 t1 = new Tipler2();
8
t1.x = 5;
9
System.out.println("Eski değer: " +
10
t1.x);
11
t1.degistir(t1);
12
System.out.println("Yeni değer: " +
13
t1.x);
14
}
15
void degistir(Tipler2 t1)
16
{
17
t1.x = t1.x + 10;
18
}
19
}
20
Ekran çıktısı:
1
Eski değer: 5
2
Yeni değer: 15
Burada da t1 nesnemizin x değişkenine 5 değerini atadık ve ekrana yazdırdık.
Daha sonra t1 nesnesini,degistir() metoduna gönderdik. Bu
metodda, t1 nesnesinin x değerini 10 artırdık. Metoddan çıkıp yeni değerimizi
yazdırdığımızda ise 15 olduğunu gördük. Çünkü metoda gönderdiğimiz
parametre, değişkenimizinorjinal değeri oluyor. Metoddaki değerin
değiştirilmesi, orjinal değerin de değişmesi demek oluyor.
Diziler de bir referans tiptir. Onu da örnek üzerinde gösterelim.
//Tipler3.java - 05.04.2014
1
2
public class Tipler3
3
{
4
public static void main(String[] args)
5
{
6
int dizi[] = {1, 6, 9};
7
System.out.println("Eski değer: " +
8
dizi[0]);
9
degistir(dizi);
10
System.out.println("Yeni değer: " +
11
dizi[0]);
12
}
13
14
static void degistir(int dizi[])
15
{
16
dizi[0] = dizi[0] + 5;
17
}
18
}
19
Ekran çıktısı:
1
Eski değer: 1
2
Yeni değer: 6
Bu örnekte de 3 elemanlı dizi tanımladık ve ilk elemanını ekrana yazdırdık.
Daha sonra bu ilk elemanı metoda gönderdik. Metod içerisinde bu dizi
elemanının değerini 5 artırdık. Metoddan çıktığımızda yeni değeri ekrana
yazdırdık ve orjinal değerin değiştiğini gördük. Çünkü diziler de
bir referans tiptir.
Şimdi de her iki yöntemi beraber kullanalım.
//Tipler4.java - 05.04.2014
1
2
public class Tipler4
3
{
4
int b;
5
public static void main(String[]
6
args)
7
{
8
int a = 4;
9
degistir1(a);
10
System.out.println(a);
11
12
Tipler4 d1 = new Tipler4();
13
d1.b = 10;
14
d1.degistir(d1);
15
System.out.println(d1.b);
16
}
17
18
void degistir(Tipler4 d1)
19
{
20
d1.b = d1.b + 25;
21
}
22
23
static void degistir1(int deger)
24
{
25
deger = deger + 5;
26
}
27
}
28
29
Ekran çıktısı:
1
4
2
35
Bu son örneğimizde, a değişkenimizin değerinin değişmediğini, b değişkeninin
ise asıl değerinindeğiştiğini gözlemledik.
Ders 51 - Yapıcılar (Constructor)
Önceki derslerimizde nesneler oluşturmayı ve o nesneler üzerinden, bulunduğu
sınıfın değişkenlerine veya metodlarına erişmeyi anlattık. Bir nesne üzerinden
bir metod çağırdığımızda, metodun alacağı parametreleri gönderiyorduk.
Sınıftan bir nesne oluşturulduğunda, derleyici otomatik olarak
bir constructor (yapıcı) metod çağırır. Bu metod, oluşturulan her nesne
için çağrılır. Yapıcılar, nesnenin ilk oluşturulduğunda alması gereken değerleri,
kullanacağı metodları belirler.

Yapıcıların adı, sınıf adı ile aynı olmak zorundadır.

Yapıcı metodlar, geriye herhangi bir değer döndüremezler.

Yapıcı metodlar, aşırı yükelenebilir. Aşırı yükleme (overloading)
kavramını Metodlar derslerinde görmüştük.

Her sınıf için bir default constuctor vardır. Bu default constructor'lar,
herhangi bir parametre almazlar. Eğer biz bunu kullanmak
istemiyorsak, parametre alan bir yapıcı kullanmak istiyorsak,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
kendimiz bir yapıcı metod yazmamız gerekir. Buna bir örnek verelim.
//Yapicilar.java - 05.04.2014
public class Yapicilar
{
int deger1, deger2; // nesne değişkenleri
public Yapicilar() // varsayılan yapıcı. Sınıf adı ile aynıdır. Parametre
almaz.
{
deger1 = 5;
}
public Yapicilar(int sayi) // parametre alan yapıcı, sınıf adı ile aynıdır.
{
deger2 = sayi;
}
public static void main(String[] args)
{
Yapicilar nesne1 = new Yapicilar();
Yapicilar nesne2 = new Yapicilar(10);
// yapıcıya parametre gönderildi
System.out.println("İlk nesnenin değeri : " + nesne1.deger1);
System.out.println("İkinci nesnenin değeri: " + nesne2.deger2);
24
25
26
27
28
}
}
Ekran çıktısı:
1
İlk nesnenin değeri : 5
2
İkinci nesnenin değeri: 10
Örneğimiz üzerinden yapıcıları inceleyelim.
1.
Burada Yapicilar adında bir sınıfımız var. Bu sınıf içerisinde
ise Yapicilar adında iki tane yapıcı metodumuz var. Yapıcı metodlar,
sınıf adı ile aynı olmak zorundadır.
2.
İlk metod parametre almıyor yani default constructordur. Bu
metod deger1 adlı değişkene 5 değerini atıyor.
3.
Diğer yapıcımız ise parametre alan bir yapıcıdır. Bu metod ise aldığı
parametreyi deger2 adlı değişkene atar.
4.
Daha sonra main metodumuz içerisinde iki adet nesne oluşturduk. İlk
nesnemiz oluşturulduğundavarsayılan yapıcı çağrılacaktır. Eğer bir
nesne oluşturursak, hemen bir varsayılan yapıcı çağırılır. Biz burada
varsayılan yapıcımızı kendimiz yazdık. Yazmasaydık derleyici
otomatik olarak oluşturacaktı. Varsayılan yapıcılar, nesne
oluşturduğumuzda parametre göndermezsek çalışır. İlk nesnemiz
için bir parametre göndermediğimizden dolayı varsayılan,
yani parametre almayan yapıcı metod çağırıldı.
5.
Diğer nesnemiz oluşturulduğunda ise 10 değerini gönderdik.
Dolayısıyla, nesne oluşturuldu ilk andaparametre alan yapıcı
metod çalıştırılır. Bu nesne için de gönderilen 10
değeri, deger2 değişkenine atandı.
6.
Son satırlarda da bu nesneler için deger1 ve deger2 değişkenlerini
ekrana yazdırdık.
Yapıcı metodların overloading yapılabileceğini söylemiştik. Bu örnekte de
görüldüğü gibi aynı isimli iki yapıcı metod yazdık ve bunlar mecburen farklı
parametreli veya parametre sıraları farklı olan metodlar olmak zorundadır.
Yapıcılar konusunda bir örnek daha verelim.
//YapicilarOverloading.java - 05.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class YapicilarOverloading
{
void metod1() // ilk metod
{
System.out.println("Parametre almayan metod
çağırıldı");
}
void metod2(int sayi1) // ikinci metod
{
System.out.println("Parametre alan metod çağırıldı");
// alınan parametreyi kullanmadık
}
public YapicilarOverloading() // ilk yapıcı
{
metod1();
}
public YapicilarOverloading(int sayi1) // ikinci yapici
{
metod2(sayi1);
}
public static void main(String[] args)
{
YapicilarOverloading nesne1 = new
YapicilarOverloading();
YapicilarOverloading nesne2 = new
YapicilarOverloading(10);
}
}
Ekran çıktısı:
1
Parametre almayan metod çağırıldı
2
Parametre alan metod çağırıldı
Şimdi örneğimizi açıklayalım.
1.
Bu örnekte metod1 ve metod2 adında iki adet metod oluşturduk. Bu
metodlar parametre alıp almadığına göre ekrana bilgilendirme mesajı
yazıyor.
2.
Daha sonra iki tane yapıcı metod yazdık. Bunlardan ilki default
yapıcı, diğeri ise parametre alan yapıcımetoddur.
3.
Parametre almayan yapıcı metod, metod1'i çağırıyor. Parametre alan
metod ise metod2'yi çağırıyor.
4.
Main metodumuzda ise nesne1 ve nesne2 adında nesneler oluşturduk.
Bunlardan nesne1oluşturulduğunda, parametre almadığı için default
constructor (varsayılan yapıcı metod) çağırılır. Bu constructor
ise, metod1'i çağırıyor.
5.
Daha sonra bu metod ekrana, "Parametre almayan metod çağırıldı"
çıktısını yazıyor.
6.
Main metodunda oluşturduğumuz ikinci nesne ise parametre alıyor.
Dolayısıyla bu nesne oluşturulduğu anda onun yapıcısı çağırılıyor.
Parametre alan yapıcı, yani ikinci yapıcı metod çağırılıyor.
7.
Bu yapıcı da metod2'yi çağırıyor ve ekrana "Parametre alan metod
çağırıldı" yazıyor.
Yapıcılar konusunu daha iyi anlamak için son bir örnek verelim. Bu
örneğimizde bir nesne dizisi oluşturalım. Örneğimizi verirken nesne dizileri
nasıl oluşturulur onu da anlatmış olalım.
1
//Yapicilar2.java - 05.04.2014
2
3
public class Yapicilar2
4
{
5
static int sayi = 0;
6
public Yapicilar2() // varsayılan yapıcı. Sınıf adı ile aynıdır. Parametre
7
almaz.
8
{
9
sayi++;
10
}
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static void dongu(Yapicilar2 nesne[])
{
for(int a = 0 ; a < 4 ; a++)
{
nesne[a] = new Yapicilar2();
}
}
public static void main(String[] args)
{
Yapicilar2 nesne[] = new Yapicilar2[4];
// nesne dizisi oluşturuldu
Yapicilar2.dongu(nesne);
System.out.println(sayi + " adet nesne oluşturuldu");
}
}
Ekran çıktısı:
1
4 adet nesne oluşturuldu
main metodumuz içerisinde 4 elemanlık bir nesne dizisi oluşturuldu. Daha
sonra bu dizi dongu adındaki bir metoda parametre olarak gönderildi. Bu
metodda da nesnemizin tüm elemanları oluşturuldu. Metodun içerisinde oluşan
her bir nesne için yapıcımız çalıştı ve sayımızı 1 artırdı. Yani amacımız, kaç
nesne oluşturulduğunu yapıcılar ile bulmak. Çünkü nesne oluşturulduğunda ilk
olarak yapıcı çağırılır ve yapıcıiçerisinde ne varsa o işlenir.
Bu dersten özet olarak çıkarmamız gereken düşünce şudur:
Nesne oluşturulduğunda ilk olarak ona ait bir yapıcı çağırılır. Eğer parametre
gönderilmemişse default constructor, gönderildiyse, ona ait olan parametreli
constructor çağırılır. 2 parametre aldıysa, 2 parametreli yapıcı çağırılır. Tek
parametre aldıysa, tek parametreli yapıcı çağırılır. Yani kendine özel
hazırlanmış yapıcı. Bu yapıcılar içerisinde herhangi bir metod çağırılabilir veya
bir değişkene atama yapılabilir veya ekrana bir şeyler yazılabilir. Bunun gibi
birçok işlem yapılabilir. Örneğin; bir yapıcının içerisine "Şuan bir nesne
oluşturuldu" gibi birçok işlem yapılabilir. Örneğin; bir yapıcının içerisine "Şuan
bir nesne oluşturuldu" gibi bir çıktı da yazdırabilirdik. Çünkü yapıcılar, nesne
oluşturulduğu ilk anda çalışır. Özet olarak yapıcılar, nesne oluşturulduğu ilk
anda yapmamızı istediğimiz şeyleri yapan bir metoddur.
Ders 52 - Kapsülleme (Encapsulation)
Kapsülleme; kısaca bir sınıfın, içerisindeki metod ve değişkenleri korumasıdır.
Bünyesindeki metod vedeğişkenlere dışarıdan erişmenin sakıncalı olduğu
durumlarda kapsülleme mekanizması kullanılır. Kapsülleme sayesinde sınıf
üyeleri, dış dünyadan gizlenir. Tabi bu gizliliğin dereceleri vardır. Bu
dereceler, erişimbelirleyiciler sayesinde olur.
Kapsülleme klasik verilen bir örnek vardır. Biz de ona benzer bir örnek verelim.
Biz bilgisayarı açma tuşuna basarız ve bilgisayar açılır ya da şöför kontağı
çevirir ve araba çalışır. Fakat kullanıcı arkaplanda ne olduğunu bilmez. Sadece
o işin nasıl yapılacağını bilir. Kapsülleme bu işi yapar.
Nesneye yönelik programlamanın temellerinden biri de kapsüllemedir. Çünkü
sınıftaki bilgilerin dışarıya kapalı olması gerekir. Şimdi bunu sağlayan erişim
belirleyicileri görelim. Bu erişim belirleyicileri, bütünlük olması açısından
kapsülleme dersinde inceleyeceğiz.
ERİŞİM BELİRLEYİCİLER (ACCESS MODIFIERS)
Daha önceki konularda karşılaştığımız ve ileride anlatacağımızı söylediğimiz
bu konu, nesneye yönelik programlamanın da bir parçasıdır. Erişim
belirleyiciler, adından da anlaşıldığı üzere sınıf elemanına erişimi sınırlandıran
anahtar kelimelerin genel adıdır. Bu anahtar
kelimeler public, private, protected'dir. Bu anahtar kelimeleri
kullanmazsak default anahtar kelimeyi kullanır. Kapsülleme'nin temelini
bu erişim belirleyicileroluşturur.
Erişim belirleyiciler konusuna somut bir örnek verelim. Ev adında bir sınıfımız
olsun. Bu ev sınıfındaki kasaadlı metod gizli olarak tanımlanmalıdır. Yani bu
kasa metoduna veya değişkenine sadece ev halkı erişebilsin. Evde önem arz
etmeyen herhangi bir şeye ise akrabalar ve komşular erişebilsin. Evde önem arz
etmeyen herhangi bir şeye ise akrabalar ve komşular erişebilsin. Yabancı kişiler
ise evdeki hiçbir şeye erişemesin. Bu tip örnekleri çoğaltabiliriz. Bu eşyaları,
önem derecesine göre başına erişim belirleyici anahtar kelimelerden birini
getirerek bunları gizleyebiliriz.
Şimdi bu anahtar kelimelerin ne anlama geldiğini söyleyelim.

public: Bir elemanı public olarak tanımlarsak, bu
elemana herkes ulaşabilir.

protected: Bir sınıfın protected olarak tanımlanmış elemanına o
sınıftan, o sınıftan türetilmiş sınıflardan ve o sınıf ile aynı
pakette bulunan sınıflar erişebilir.

private: private olarak tanımlanmış sınıf elemanlarına, yalnızca o
sınıftan erişilebilir. O sınıftan türetilensınıflardan veya aynı
pakette bulunan sınıflardan erişilemez.

default: Herhangi bir erişim belirleyici
tanımlanmamışsa, default olarak kabul edilir. Default tanımlanmış
sınıf elemanlarına, o sınıftan ve aynı paketteki sınıftan erişilebilir.
Bu anahtar kelimelerin kullanımına örnek verelim.
PRIVATE ANAHTAR KELİMESİ
İlk olarak private anahtar kelimesini gösterelim. Yukarıda tanımını yapmıştık.
Örnek üzerinde de gösterelim.
1
//Ev.java - 05.04.2014
2
3
package Private_Aynı_Sınıf;
4
5
public class Ev
6
{
7
private void kasa() // private metod tanımlama
8
{
9
System.out.println("Gizli kasa");
10
}
11
12
13
14
15
16
17
18
19
20
private String belge = "Gizli Belge"; // private değişken
tanımlama
public static void main(String[] args)
{
Ev anne = new Ev(); // Ev sınıfından nesne oluşturuldu
anne.kasa();
// anne nesnesi, kasaya ulaşmaya
çalışıyor
System.out.println(anne.belge);
}
}
Ekran çıktısı:
1
Gizli kasa
2
Gizli Belge
Bu örnekte private konusuna bir örnek verdik. Burada sınıf tanımlamasının
hemen altında bir metod vedeğişken tanımladık ve bunları private olarak
belirledik. Daha sonra aynı sınıf içerisinde main metodunda
birnesne oluşturarak bu elemanlara erişmeye çalıştık. Aynı sınıftan eriştiğimiz
için hata vermedi ve privateelemanlara erişebildik. Programımızın
başladığı main metodu, o sınıfın içindedir. Başka bir sınıfta main metodu
tanımlayıp ve nesneyi orada türetip, oradan erişmeye çalışsaydık
erişemeyecektik.
Şimdi ise aynı sınıftan değil de başka bir sınıftan erişmeye çalışalım. Bunun
için Kisiler adında bir sınıf daha oluşturuyoruz. (Aynı paket içerisinde)
Ev Sınıfı:
1
//Ev.java - 05.04.2014
2
3
package Private_Farklı_Sınıf; // paketler aynı
4
5
public class Ev
// ev sınıfı
6
{
7
private void kasa() // private metod
8
{
9
System.out.println("Gizli kasa");
10
}
11
12
13
14
private String belge = "Gizli Belge"; // private
değişken
}
Kisiler Sınıfı:
//Kisiler.java - 06.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package Private_Farklı_Sınıf;
aynı
// paketler
public class Kisiler // Kisiler sınıfı
{
public static void main(String[] args)
{
Ev anne = new Ev(); // nesne
oluşturuldu
anne.kasa();
// erişilemez
System.out.println(anne.belge); //
erişilemez
}
}
Başka bir sınıf olan Kisiler adlı sınıftan nesne
türetip Ev sınıfının private elemanlarına erişmeye çalıştığımızda, yukarıdaki
gibi altını çiziyor ve erişemeyeceğimizi söylüyor. Görüldüğü
gibi private elemanlara,sadece tanımlandığı sınıf içerisinden erişilebilir. Ne
başka bir sınıftan türetilen nesne ile ne herhangi bir sınıftan ne de aynı pakette
olan sınıf içerisinden erişilemez.
PROTECTED ANAHTAR KELİMESİ
Şimdi protected anahtar kelimesinin kullanımını görelim ve örnekler üzerinde
anlatalım. Tanımını dersimizin başında yapmıştık.
Yukarıda yaptığımız örneği bir de protected için yapalım.
Ev Sınıfı:
//Ev.java - 06.04.2014
1
2
package Protected_Farklı_Sınıf;
3
4
public class Ev
5
{
6
protected void bilgisayar() // protected metod tanımlandı
7
{
8
System.out.println("Bilgisayar metodu");
9
}
10
protected String fatura = "Faturalar"; // protected değişken
11
tanımlandı
12
}
13
14
Kisiler Sınıfı:
//Kisiler.java - 06.04.2014
1
2
package Protected_Farklı_Sınıf; // paketler aynı
3
4
public class Kisiler // Kisiler sınıfı
5
{
6
public static void main(String[] args)
7
{
8
Ev akraba = new Ev(); // akraba nesnesi
9
akraba.bilgisayar(); // akraba nesnesi, metoda erişmeye
10
çalışıyor
11
System.out.println(akraba.fatura);
12
}
13
}
14
15
Ekran çıktısı:
1
Bilgisayar metodu
2
Faturalar
Bu örnekte Ev sınıfının elemanlarını protected olarak ayarladık. Yani dedik ki;
bu elemanlara sadece evsınıfından olanlar, bu sınıftan türetilmiş sınıflar ve
bu Ev sınıfı ile aynı paketten olan sınıflar erişebilsin. Biz de bu Ev sınıfı
ile aynı paketten olan sınıflar erişebilsin. Biz de bu Ev sınıfı ile aynı
paketten olan Kisiler adlı sınıfı oluşturduk. Bu sınıftan akraba adında bir
nesne oluşturduk ve görüldüğü gibi bu nesne
ile Ev sınıfınınprotected elemanlarına erişebildik. Sınıf Türetme
(Kalıtım) konusunu anlatmadığımız için buna değinmeyeceğiz.
Fakat protected elemanlara, türetilmiş sınıflardan da erişilebilir.
Eğer Kisiler sınıfının en üstünde bulunan paket tanımlamasında package
Protected_Farklı_Sınıf;tanımlamasını package
Protected_Farklı_Sınıf2; yapsaydık, bu protected elemanlara erişemeyecektik.
Çünkü aynı paketten olmayacaklardı.
protected elemanlara aynı pakatten erişilebildiğini gördük. Aynı paketten
erişilebiliyorsa aynı sınıftan da erişilebilir. Bunu da gösterelim.
Sadece Ev sınıfı üzerinden anlatalım.
Ev Sınıfı:
1
//Ev.java - 05.04.2014
2
3
package Protected_Aynı_Sınıf;
4
5
public class Ev
6
{
7
private void bilgisayar() // protected tanımlanmış metod
8
{
9
System.out.println("Bilgisayar metodu");
10
}
11
protected String fatura = "Faturalar"; // protected tanımlanmış
12
değişken
13
public static void main(String[] args)
14
{
15
Ev akraba = new Ev();
16
akraba.bilgisayar(); // aynı sınıftan protected elemanlara
17
erişilebilir
18
19
20
21
System.out.println(akraba.fatura);
// aynı sınıftan her zaman erişilebilir.
}
}
Bu örnekte de aynı sınıftan protected elemanlara erişmeyi gördük. Aynı
sınıftan erişmek için anahtar kelimenin önemi yoktur. Kalıtım konusunda alt
sınıf kavramını göreceğiz ve alt sınıflardan da üst sınıfın
protected elemanlarına erişilebilir.
Kısacası protected elemanlara o sınıftan, türetilen sınıftan, aynı pakette olan
başka bir sınıftan erişilebilir.
PUBLIC ANAHTAR KELİMESİ
Şimdi de public anahtar kelimesine örnek verelim.
İlk olarak bildiğimiz gibi aynı sınıftan erişmeyi görelim. Bunda herhangi bir
sıkıntı yok. Çünkü bunu her şekilde yapabiliyoruz.
//Ev.java - 06.04.2014
1
2
package public_aynı_sınıf;
3
4
public class Ev
5
{
6
private void adres() // public metod tanımlandı
7
{
8
System.out.println("Ev adresi");
9
}
10
public int KatSayisi = 3; // public değişken
11
tanımlandı
12
13
public static void main(String[] args)
14
{
15
Ev halk = new Ev();
16
halk.adres();
// herkes erişebilir
17
System.out.println(halk.KatSayisi);
18
}
19
}
20
21
Ekran çıktısı:
1
Ev adresi
2
3
Burada public olarak evin adresini ve kat sayısını verdik. Yani bu elemanlara
herkes erişebilir.
Bu örnekte aynı sınıftan public elemanlara erişmeyi gördük. Şimdi ise başka
sınıftan ve başka pakettenerişmeyi görelim.
Ev Sınıfı:
//Ev.java - 06.04.2014
1
2
package Public_Farklı_Sınıf;
3
4
public class Ev
5
{
6
protected void adres()
7
{
8
System.out.println("Ev
9
adresi");
10
}
11
public int katSayisi = 3;
12
}
13
14
Kisiler Sınıfı:
1 //Kisiler.java - 06.04.2014
2
3 package Public_Farklı_Sınıf;
4
5 public class Kisiler
6 {
7
public static void main(String[] args)
8
{
9
Ev halk = new Ev();
10
halk.adres();
11
System.out.println(halk.katSayisi);
12 }
13 }
14
15
Bu örnekte ekran çıktımız yine aynı olacaktır.
Yani halk nesnesi,Ev sınıfındaki public elemanlara erişebilecektir ve ekrana
değerlerini yazacaktır. Eğer Kisiler sınıfındaki paket
tanımlamasında paket1 adlı paketi paket2 yaparsak, farklı paketlerde olduğu
için Ev sınıfının elemanlarına erişebilecek miyiz, onu görelim.
Ev sınıfımız aynı kalsın ve biz Kisiler sınıfının yeni halini şu şekilde yapalım.
Kisiler Sınıfı:
1 //Kisiler.java - 06.04.2014
2
3 package Public_Farklı_Sınıf2;
4 import Public_Farklı_Sınıf.Ev;
5
6 public class Kisiler
7 {
8
public static void main(String[] args)
9
{
10
Ev halk = new Ev();
11
halk.adres();
12
System.out.println(halk.katSayisi);
13 }
14 }
15
16
Ekran çıktısı:
1
Ev adresi
2
3
Örneğimizde görüldüğü gibi farklı paketlerde olsak bile, public elemanlara
erişebiliriz. Biz burada halkadında bir nesne oluşturduk yani bir ev ile
ilgili public bilgilere, tüm halkın ulaşabildiğini göstermek için bu şekilde
adlandırdık. Ayrıca Ev sınıfı kullanabilmek için import ettik. Farklı paketler de
olsa, o paketi sınıfa dahil ederek public elemanlara erişebiliriz. Yine aynı
şekilde türetilmiş sınıflardan da erişilebilir.
!
Istisnalar:
Eğer alanımızın başına bir erişim belirleyici yazmazsak default olarak
algılanır. default olan alanlara da yalnızca o sınıftan ve aynı paketten
erişilebilir.
Istisnalar:
!
Java'da .java uzantılı dosya içerisinde birden fazla
sınıf kullanacaksak, yalnızca bir tanesi public olarak tanımlanabilir.
Aynı yerde iki veya ikiden fazla sınıf public olamaz.
Nottaki özelliğe bir örnek verelim:
//Ev.java - 06.04.2014
1
2
public class Ev
3
{
4
public static void main(String[]
5
args)
6
{
7
}
8
class Kisiler // bu sınıf public
9
olamaz
10
{
11
}
12
}
13
Burada Ev sınıfını public olarak tanımladığımız için aynı yerde, public olan
başka bir sınıf tanımlayamadık. Dolayısıyla Kisiler sınıfını default olarak
tanımlamak zorunda kaldık.
Istisnalar:
!
Erişim belirleyicileri doğru kullanmak, proje açısından önemlidir.
Eğer yanlış bir kullanımında bulunursak izin verilmeyen kişiler, bazı
erişilmemesi istenen bilgileri okuyabilir.
Şimdi de kapsüllemede önemli bir yeri olan Getter ve Setter metodları
görelim. Ön bilgi verecek olursak bu metodlar, private elemanlara, başka
sınıflardan kontrollü bir şekilde erişmeyi sağlar.
GETTER VE SETTER METODLARI
Kapsülleme ile iç içe olan bir konuda getter ve setter metodları konusudur.
Kapsülleme'de bu metodların da görevi vardır.
Erişim belirleyicileri anlattığımızda private elemanlara, başka bir sınıftan
erişemeyeceğimizi söylemiştik. Java'da ve diğer dillerde, bu private elemanlara
erişmenin bir yolu vardır. C# dilinde bunlara get - setmetodları denir. Java'da
ise bunlar getter - setter metodlar olarak adlandırılır.
Bu metodlar sayesinde private olan üyeler okunabilir veya
değerleri değiştirilebilir. Okuyabilmek içingetter, yazabilmek
içinse setter metodlar kullanılır.
Getter metodlar, okuma yaptığı için parametre almazlar. Setter metodlar
ise private üyelere değer atadığı için parametre alırlar.
GETTER VE SETTER METODLARINI TANIMLAMA
Ön bilgi verdikten sonra şimdi bir örnek getter ve setter metodları oluşturalım
ve örnek üzerinde inceleyelim.
1
//GetterSetter.java - 05.04.2014
2
3
package Getter_ve_Setter_Metodları;
4
5
public class GetterSetter
6
{
7
private int deger; // private değişkenler
8
tanımlandı
9
private String ad;
10
public int getDeger() // getter metod
11
{
12
return deger;
13
}
14
public void setDeger(int deger) // setter
15
metod
16
{
17
this.deger = deger;
18
}
19
public String getAd() // getter metod
20
{
21
return ad;
22
}
23
public void setAd(String ad) // setter metod
24
25
26
27
28
29
30
31
32
33
34
35
{
this.ad = ad;
}
public static void main(String[] args)
{
GetterSetter n1 = new GetterSetter();
n1.setAd("Okan");
System.out.println(n1.getAd());
n1.setDeger(5);
System.out.println(n1.getDeger());
}
}
Ekran çıktısı:
1
Okan
2
5
Örneğimizi açıklayalım:
1.
main metodunda bir nesne oluşturuyoruz.
2.
Bu nesne üzerinden setAd() metodunu çağırıyoruz ve parametre
olarak Okan veriyoruz. Bunun ileprivate değişken
olan ad değişkenine, Okan parametresini atıyoruz.
3.
n1.getAd() ile atadığımız bu değişkeni ekrana yazdırıyoruz. Bu
metod return ad; satırına sahip olduğu için bize ad değişkenini
döndürüyor.
4.
Daha sonra bu nesne üzerinden setDeger() metodunu çağırıyoruz ve
parametre olarak 5 değerini gönderiyoruz. Bunun ile private değişken
olan deger değişkenine, 5 parametresini atıyoruz.
5.
Son olarak n1.getDeger() metodunu çağırıyoruz. Bu metod, return
deger; satırına sahip olduğu için bize deger değişkenini döndürüyor.
Istisnalar:
!
Getter metodlara istediğimiz adı verebiliriz. Fakat get kelimesi ile
başlatmak, kodun okunabilirliğini artıracaktır. Bu şekilde görüldüğü
gibi private elemanların değerlerini okuyabildik ve üzerinde değer
yazabildik.
private elemanlara erişmeyi yalnızca getter ve setter metodlar ile yapmayız.
Bir sınıfın yapıcısında daprivate elemanlara değer atayabiliriz. Fakat
değer okuyamayız. Çünkü yapıcılar geriye değer döndürmezler. Ayrıca
yapıcılar içerisinde başka bir metod da çağırılabilir.
Şimdi aynı örneği bir de yapıcılar ile yapalım.
1
//GetterSetter2.java - 05.04.2014
2
3
package Getter_ve_Setter_Metodları;
4
5
public class GetterSetter2
6
{
7
private int deger; // private alanlar
8
private String ad;
9
10
public int getDeger()
11
{
12
return deger;
13
}
14
15
public void setDeger(int deger)
16
{
17
this.deger = deger;
18
}
19
20
public String getAd()
21
{
22
return ad;
23
}
24
public void setAd(String adi)
25
{
26
this.ad = adi;
27
}
28
public GetterSetter2(String adi, int sayi) //
29
yapıcı
30
{
31
setAd(adi); // setter metod çağırıldı
32
setDeger(sayi); // setter metod çağırıldı
33
}
34
public static void main(String[] args)
35
{
36
37
38
39
40
41
GetterSetter2 n1 = new GetterSetter2("Sezer",
10);
System.out.println(n1.getAd());
System.out.println(n1.getDeger());
}
}
main metodundaki ilk satırda nesne oluştururken,
yapıcımıza Sezer ve 10 değerlerini gönderdik. Yapıca ise, bu alınan
değerler, setter metodlara gönderiliyor. O yüzden
artık main içerisinde setter metodları kullanarak değer atamaya gerek kalmadı.
Ayrıca yapıcımız içinde setter metodlarını çağırmak yerine alınan değerleri
doğrudan private değişkenlere atayabilirdik. Bunun için yapıcımızda
kullanacağımız satır aşağıdadır.
1
ad = adi;
2
deger = sayi;
... şeklinde olurdu.
ECLIPSE ÜZERİNDE KISAYOLDAN GETTER VE SETTER
OLUŞTURMA
Derslerimizde Eclipse IDE üzerinde anlattığımız için Eclipse üzerinde
kısayoldan getter ve settermetodları nasıl ekleyebileceğimizi görelim.
1.
Sol taraftaki Project Explorer üzerinde, çalıştığımız
projenin src klasörünü açalım.
2.
src klasörünün altında eğer paketimiz varsa paketimizi seçelim.
3.
Daha sonra hangi sınıf içerisinde getter ve setter metodlarını
oluşturmak istiyorsak, o sınıf üzerine sağ tıklayalım ve aşağıda
bulunan şekildeki adımları takip edelim.
Source kısmında istediğimiz metodları ekleyebiliriz.
Ders 53 - This Anahtar Kelimesi
Java'da this anahtar kelimesinin kullanılma amacını şöyle açıklayabiliriz.
Önceki derslerimizdeki örneklerde bir metoda parametre gönderiyorduk ve bazı
metodlarda bu alınan parametreyi bir nesne değişkenine atıyorduk.
Bir örnek üzerinde gösterelim:
//ThisAnahtarKelimesi.java - 05.04.2014
1
2
public class ThisAnahtarKelimesi
3
{
4
String ad;
5
6
public void degistir(String ad)
7
{
8
this.ad = ad;
9
}
10
11
public static void main(String[] args)
12
{
13
ThisAnahtarKelimesi t = new
14
ThisAnahtarKelimesi();
15
t.degistir("Okan");
16
System.out.println(t.ad);
17
}
18
}
19
20
Ekran çıktısı:
1
Okan
Böyle bir sınıfımız olduğunu düşünelim. String tipinde bir ad değişkeni
tanımladık. Bu bir nesne değişkenidir. Daha sonra degistir adında bir metod
oluşturduk. Bu metod, aldığı String tipindeki adparametresini, nesne değişkeni
olan ad değişkenine atıyor. Burada alınan parametre değişkeninin adı ile
atadığımız nesne değişkeninin adı aynı olduğu için this anahtar kelimesini
kullanmamız gerekiyor. Eğer bunlar farklı olsaydı, this anahtar kelimesini
kullanmamız gerekmeyecekti.
Eğer bu örnekte this anahtar kelimesini yazmasaydık, null çıktısı verecektir.
Eğer gönderdiğimiz parametrenin adı, atadığımız değişkenin adı ile aynı
olmasaydı, this anahtar kelimesini yazmaya gerek kalmayacaktı.
Yukarıdaki örneği bir de farklı parametre adı ile yapalım.
//ThisAnahtarKelimesi2.java - 05.04.2014
1
2
public class ThisAnahtarKelimesi2
3
{
4
String ad;
5
6
public void degistir(String adi)
7
{
8
ad = adi; // this kullanılmadı çünkü isimler farklı
9
}
10
11
public static void main(String[] args)
12
{
13
ThisAnahtarKelimesi2 t = new
14
ThisAnahtarKelimesi2();
15
t.degistir("Okan");
16
System.out.println(t.ad);
17
}
18
}
19
20
Bu kod da "Okan" çıktısı verecektir. Gönderdiğimiz parametre adı ile nesne
değişkenimizin adı farklı olduğu için this anahtar kelimesini kullanmaya gerek
kalmadı.
Başka bir tanımla anlatmak gerekirse, this anahtar kelimesi o anda işlem yapan
nesnenin referansınıdöndürür. Bu referans ile biz nesne
değişkenlerine erişiriz. Bir metod çağırıldığında, o metodun hangi nesne
tarafından çağırıldığı bilinebilir. Sonuç olarak, this anahtar kelimesi, bu gibi
isim çakışmalarında karışıklığı önlemek amacıyla kullanılır. this anahtar
kelimesi kullanılarak, nesne değişkeninin kullanılacağı belirtilir.
Istisnalar:
! this anahtar kelimesi, yalnızca yapıcı
metodlarda değil tüm
metodlarda kullanılabilir.
this anahtar kelimesinin bir başka kullanım amacı da, aynı sınıf içerisindeki
başka bir yapıcıyı çağırmaktır. Diyelim ki biri 1 parametre, diğeri de 2
parametre alan 2 yapıcımız olsun. 1 parametre alan yapıcıdaki parametreye 1
parametre daha ekleyerek 2 parametre alan yapıcı metodu çağırabiliriz.
Bunu bir örnek üzerinde inceleyelim ve konuyu daha iyi anlayalım.
//ThisAnahtarKelimesi3.java - 05.04.2014
1
2
public class ThisAnahtarKelimesi3
3
{
4
String ad;
5
String soyad;
6
7
public ThisAnahtarKelimesi3(String ad) // tek parametre alan yapıcı
8
{
9
this(ad, "Bilke"); // this ile 2 parametreli yapıcı çağrıldı
10
}
11
12
public ThisAnahtarKelimesi3(String ad, String soyad) // iki
13
parametreli yapıcı
14
{
15
System.out.println(ad + " " + soyad);
16
}
17
18
public static void main(String[] args)
19
{
20
ThisAnahtarKelimesi3 nesne = new
21
ThisAnahtarKelimesi3("Okan");
22
}
23
}
24
Ekran çıktısı:
1
Okan Bilke
Bu örnekte ad ve soyad olarak iki nesne değişkeni tanımladık. Bunun yanında
1 ve 2 parametre alan iki yapıcı tanımladık. main metodu içerisinde nesne
oluşturduğumuzda tek bir String parametresi gönderdik ve dolayısıyla tek
parametre alan yapıcı çalıştı. Bu yapıcıda ise this ile diğer yapıcıyı çağırdık.
Çağırırken de yanına 2 parametreli olması için bir String parametresi daha
ekledik. Böylece 2 parametremiz oldu ve iki parametre alan yapıcıyı çağırarak
çalıştırdık.
this anahtar kelimesinde bahsedeceğimiz son nokta ise, this anahtar
kelimesinin bir metoddan geriye değer olarak döndürebilmesidir. Herhangi
bir metod içerisinde return this; dediğimizde o metoddan geriye, o an çalışan
nesnenin referansı döner. Bunu, o anki çalışan metodun hangi nesne üzerinden
çağırıldığını öğrenmek için kullanabiliriz.
Ders 54 - Static Anahtar Kelimesi
static anahtar kelimesi, kısaca sınıftaki alanlara nesne oluşturmadan erişmeyi
sağlar. Şimdi bunu daha ayrıntılı bir şekilde anlatalım.
Bir sınıf düşünelim. İçerisinde kişi bilgilerinin
tutulduğu ad, soyad, cinsiyet gibi alanlar olsun. Daha sonra bu sınıftan
nesneler oluşturduğumuzda her kişi için ad, soyad, cinsiyet gibi bilgiler
tutulacaktır. Görüldüğü gibi her kişi için bu alanlar vardır ve farklıdır.
Bunlara nesne değişkenleri denir. Her oluşturulan kişi nesnesi için
bellekte ad, soyad, cinsiyet alanları tutulur. Buradaki
her ad, soyad ve cinsiyet değişkeninin ait olduğu birnesne vardır.
Java'da her nesne için ayrı tutulan alanlar değil de bir sınıf için ortak tutulan
alanlar oluşturmak istersek, bunun için yapmamız gereken static anahtar
kelimesi kullanmaktır. Oluşturacağımız alanların başına staticanahtar kelimesi
getirerek oluşturacağımız değişkenler, sınıf değişkenleri olarak adlandırılır. Bu
alanlara, sınıftan bir nesne oluşturmadan doğrudan sınıf adı ile erişim
yapılabilir.
static olarak tanımlanmış değişkenler, yani sınıf değişkenleri, o sınıftan
oluşturulan her nesne için ayrı ayrı oluşturulmaz. Dolayısıyla sınıf değişkenleri,
bellekte tek bir yerde tutulurlar. Ayrıca sınıf değişkenleri, o sınıftan nesne
oluşturulmasa bile bellekte bunun için yer ayrılır. Fakat nesne değişkenlerinde,
nesne oluşturulduğunda o değişken bellekte yer kaplamaya başlar.
Static anahtar kelimesine, sınıf ve nesne değişkenleri konusunda değinmiş ve
giriş yapmıştık.
Şimdi bunu bir örnekle pekiştirelim.
//Kisiler.java - 06.04.2014
1
2
package staticanahtar;
3
4
public class Kisiler
5
{
6
private String ad;
// nesne değişkeni
7
private String soyad;
// nesne değişkeni
8
private String cinsiyet; // nesne değişkeni
9
public static int sayi = 0; // sınıf değişkeni
10
11
public Kisiler(String ad, String soyad, String
12
cinsiyet)
13
{
14
this.ad = ad;
15
this.soyad = soyad;
16
this.cinsiyet = cinsiyet;
17
sayi++; // static değişkenin değeri artırıldı.
18
}
19
}
20
21
Programımızın bir de main metodunu yazalım ve inceleyelim.
1
//MainMetodu.java - 06.04.2014
2
3
package staticanahtar;
4
5
public class MainMetodu
6
{
7
public static void main(String[] args)
8
{
9
System.out.println("Başlangıçta kişi sayısı: " + Kisiler.sayi);
10
// sayı değişkenine sınıf adı ile eriştik
11
Kisiler kisi1 = new Kisiler("Okan", "Bilke", "Erkek");
12
Kisiler kisi2 = new Kisiler("Onur", "Bilke", "Erkek");
13
Kisiler kisi3 = new Kisiler("Mustafa", "Bilke", "Erkek");
14
System.out.println("Nesneler oluşturulduktan sonraki kişi sayısı: " +
kisi1.sayi);
}
}
15
16
17
18
19
Ekran çıktısı:
1
Başlangıçta kişi sayısı: 0
2
Nesneler oluşturulduktan sonraki kişi sayısı: 3
Örneğimizi açıklayalım.
1.
main metodumuz içerisinde ilk olarak kişi sayımızı yazdırdık.
Buradaki sayi değişkenine, görüldüğü gibi doğrudan sınıf adı ile
eriştik, herhangi bir nesne oluşturmadık.
2.
Daha sonra 3 tane nesne oluşturduk ve ilk değerlerini
verdik. Kisiler sınıfının yapıcısı ile bu
değerler ad,soyad ve cinsiyet değerlerine atandı. Kisiler sınıfımızın
yapıcısında, sayi değişkenimizin değerini, her nesne oluşturmada 1
artırdık. Çünkü bir sınıftan nesne oluşturulduğunda ilk olarak
oluşturulan sınıfın yapıcısı çağırılır.
3.
Son olarak da nesneler oluşturulduktan sonraki sayi değişkenimizin
değerini ekrana yazdırdık. 3 adetkisi nesnesi oluşturduğumuz için ve
bunlar oluşturulurken, çağırılan her yapıcıda sayi değeri arttığı için
ekrana 3 yazdı. Bu değişkene ise sınıf adı ile değil nesne ile eriştik.
Yani burada sınıf değişkenlerini, oluşturulan tüm nesneler etkiler. Bu yüzden
sınıf değişkenleri staticolarak tanımlanır ve bu değişkenlere erişmek için nesne
oluşturmak gerekmez.
STATIC METODLAR
Değişkenleri static olarak tanımladığımız gibi metodları da static olarak
tanımlayabiliriz. Bu şekilde tanımlanmış metodlara en iyi örnek Math sınıfının
metodlarıdır. Örneğin; Math sınıfının sqrt() fonksiyonunu kullanabilmek için
bu sınıftan bir nesne oluşturmak gerekmez.
Doğrudan Math.sqrt(); fonksiyonunu kullanarak karekök aldırabiliriz. Bunun
sebebi; Math sınıfındaki tüm metodların static olarak tanımlanmasıdır.
Static metodların kullanımına bir örnek verelim.
//Kisiler.java - 06.04.2014
1
2
public class Kisiler
3
{
4
public static String ad =
5
"Okan";
6
7
public static int isimGetir()
8
{
9
return ad;
10
}
11
}
12
13
Metodumuzun başına da static anahtar kelimesini getirdik. Bunu, sınıf adı ile
erişmek için yaptık. staticmetodlara nesne oluşturmadan da erişebiliriz.
Bu static metodlar içerisinden bir değişkene veya başka bir metoda ulaşmak
istersek, doğrudan çağırmak mı gerekir? Burada bir not düşmemiz gerekiyor.
Istisnalar:
Static metodlar içerisinden, static olmayan bir değişkene
! erişilemez ve static olmayan bir metod çağırılamaz. Fakat
bunun tam tersi olabilir. Yani static olmayan bir metod
içerisinden, static olan bir değişkene
erişilebilir ve static olan bir metod çağırılabilir.
static bir metod içerisinden, static olmayan bir değer döndürmeye çalışırsak
veya bir static olmayanmetod çağırırsak, aşağıdaki hatayı alırız.
1
Cannot make a static reference to the non-static field ad
Neden böyle bir hata alırız?
Bir nesne olmadığında static metodlara erişebiliriz. Fakat nesnesiz olarak
eriştiğimiz bu metoddan, staticolmayan bir metoda veya değişkene ulaşamayız.
Çünkü bunlara ulaşmak için nesne gerekir.
Bu konuyu Ders 35 - Static Metodlar dersinde daha detaylı incelemiştik.
Static olan metodlara, sınıf adı.metodadı(); şeklinde erişebiliyoruz. Eğer sınıf
adını da yazmadan doğrudan metod adı ile erişmek istersek, ne yapmamız
gerekir? Bunun için ise Static Import yöntemini kullanacağız.
STATIC IMPORT
Bunu math.sqrt() metodu üzerinden anlatalım. Biz
doğrudan sqrt() fonksiyonunu çağırarak işlem yaptırmak istiyorsak, yapmamız
gereken yukarıda import ettiğimiz java.lang.Math.* sınıfının
başına staticanahtar sözcüğünü getirmektir. Bunu bir örnekle açıklayalım.
1
//MainMetodu.java - 06.04.2014
2
3
import static java.lang.Math.*;
4
5
public class MainMetodu
6
{
7
public static void main(String[] args)
8
{
9
System.out.println("5 üzeri 2: " + pow(5, 2));
10
}
11
}
12
13
Ekran çıktısı:
1
5 üzeri 2: 25.0
Görüldüğü gibi import kelimesinden sonra static getirerek Math sınıfının
bütün metodlarını ekledik. ArtıkMath sınıfının bütün
metodlarını doğrudan kullanabiliriz.
Ders 55 - Enum Kavramı
Enum'lar sınıflara benzer. Kendilerine ait yapıcıları vardır.
Bünyesinde üyeler barındırır.
Enum tanımlamak için enum anahtar kelimesi kullanılır. Konuyu anlattıktan
sonra Enum kavramının ne olduğunu, ne işe yaradığını daha iyi anlayacaksınız.
ENUM TANIMLAMA
Basit bir enum tanımlaması yapalım.
enum Hayvanlar {KEDI, KOPEK, YILAN,
1
TAVSAN}
2
// enum elemanlarının arasına virgül koyulur
Şimdi buradaki elemanları çağıran bir sınıf yapalım.
1
//Enum.java - 06.04.2014
2
3
enum Hayvanlar
4
{
5
KEDI, KOPEK, YILAN, TAVSAN
6
}
7
public class Enum
8
{
9
public static void main(String[] args)
10
{
11
System.out.println(Hayvanlar.KEDI);
12
System.out.println(Hayvanlar.KOPEK);
13
System.out.println(Hayvanlar.YILAN);
14
System.out.println(Hayvanlar.TAVSAN);
15
}
16
}
17
18
Ekran çıktısı:
1
KEDI
2
KOPEK
3
YILAN
4
TAVSAN
Enum içerisindeki elemanlara, enum adı ile erişebiliyoruz. Bu enum
içerisindeki elemanlara değerler de verebiliriz.
İçerisinde yapıcı olan ve enum elemanlarına değer verdiğimiz bir enum
tanımlarsak:
//Arabalar.java - 06.04.2014
1
2
enum Arabalar
3
{
4
AUDI(200), BMW(190), OPEL(180), FIAT(160); // enum elemanlarına
5
değer verdik
6
public int hiz;
7
Arabalar(int hiz) // enum yapıcısı. Public olamaz.
8
{
9
this.hiz = hiz;
10
}
11
}
12
13
Burada enum yapımızın adı Arabalar'dır. İçerisinde 4 eleman var ve bunların
değerlerini parantez içerisinde verdik. Yapıcımız da enum ile aynı isimdedir.
Aldığı int değerini enum içerisindeki elemanların hizdeğerine atar (parantez
içerisindeki değere). Tabi bunun için de int tipinde bir hiz değişkeni
tanımladık. Hemen ilk notumuzu da düşelim.
Istisnalar:
! Enum içerisindeki yapıcılar public olamaz ve
enum'lar, bir sınıftan türetilemezler (miras
alamazlar).
Yukarıdaki yapı için de bir örnek verelim.
1 //Enum2.java - 06.04.2014
2
3 enum Arabalar
4 {
5
AUDI(200), BMW(190), OPEL(180), FIAT(160); // enum elemanlarına
6 değer verdik
7
public int hiz;
8
Arabalar(int hiz) // enum yapıcısı. Public olamaz.
9
{
10
this.hiz = hiz;
11
}
12 }
13
14 public class Enum2
15 {
16
public static void main(String[] args)
17
{
18
System.out.println(Arabalar.AUDI.hiz);
19
System.out.println(Arabalar.BMW.hiz);
20
System.out.println(Arabalar.OPEL.hiz);
21
System.out.println(Arabalar.FIAT.hiz);
22
}
23 }
24
Ekran çıktısı:
1
200
2
190
3
180
4
160
Bu örnekte, enum içerisindeki değerleri ekrana yazdırdık. Burada değişken
olarak belirlediğimiz hiz değişkeni, parantez içerisindeki değerler
oluyor. enum içerisindeki her elemanın bir hız değişkeni olmuş oldu.
Örneğimizde de bunu yazdırdık.
enum içerisindeki elemanların değerlerini kendimiz de verebilirdik. Bunu da
gösterelim.
1 //Enum3.java - 06.04.2014
2
3 enum Arabalar2
4 {
5
AUDI, BMW, OPEL, FIAT;
6
public int hiz;
7 }
8
9 public class Enum3
10 {
11 public static void main(String[] args)
12 {
13
Arabalar2.AUDI.hiz = 230;
14
Arabalar2.BMW.hiz = 210;
15
System.out.println(Arabalar2.AUDI.hiz);
16
System.out.println(Arabalar2.BMW.hiz);
17 }
18 }
19
20
Ekran çıktısı:
1
230
2
210
enum içerisindeki elemanlar yalnızca int tipinde değerleri almazlar. Bir
de String tipinde veri aldığı duruma örnek verelim.
//Enum4.java - 06.04.2014
1
2
enum Arabalar3
3
{
4
AUDI("Siyah"), MERCEDES("Beyaz");
5
public String renk;
6
7
Arabalar3(String renk) // yapıcımız String tipinde
8
parametre aldı
9
{
10
this.renk = renk;
11
}
12
}
13
14
public class Enum4
15
{
16
public static void main(String[] args)
17
{
18
System.out.println(Arabalar3.AUDI.renk);
19
System.out.println(Arabalar3.MERCEDES.renk);
20
}
21
}
22
23
Ekran çıktısı:
1
Siyah
2
Beyaz
Örnekte de yaptığımız üzere enum elemanları String tipte değerleri almıştır.
ENUM İÇERİSİNDEKİ ELEMANLARI YAZDIRMAK
Enum içerisindeki elemanları tek tek yazdırmak yerine bilindiği
gibi for döngüsü ile yapabiliriz. Fakat foryerine foreach (gelişmiş for döngüsü)
yapısını kullanacağız. foreach ile enum elemanlarını yazdırma ile ilgili bir
örnek verip bu özelliği geçelim.
//Enum5.java - 07.04.2014
1
2
enum Arabalar4
3
{
4
AUDI("Siyah"), MERCEDES("Beyaz");
5
public String renk;
6
7
Arabalar4(String renk) // yapıcımız String tipinde
8
parametre aldı
9
{
10
this.renk = renk;
11
}
12
}
13
14
public class Enum5
15
{
16
public static void main(String[] args)
17
{
18
for(Arabalar4 a: Arabalar4.values())
19
{
20
System.out.print(a.name() + " - ");
21
System.out.println(a.renk);
22
}
23
}
24
}
25
26
Ekran çıktısı:
AUDI - Siyah
1
MERCEDES 2
Beyaz
foreach dediğimiz döngü tipinde önce değişkenin tipi yazılıyordu, fakat burada
değişkenimizin tipiArabalar4'dır. Çünkü o tipteki bir elemandır. Dizilerdeki
gibi düşünürsek Arabalar4.values() dediğimizde de o enumdaki elemanları
kastediyoruz. Daha sonra a.name ile bu enum verilerini yazdırıyoruz
ve a.renk diyerek de parantez içerisindeki değerleri yazdırıyoruz. a.name değil
de sadece a yazsaydık, yine aynı sonucu elde ederdik. Çünkü buradaki a, enum
içerisindeki bir elemana karşılık geliyor.
ORDİNAL METODU İLE ENUM ELEMANLARININ İNDİSİNİ
ÖĞRENME
Enumlar yapı olarak hem dizilere hem de sınıflara benzerler. Diziye benzeyen
kısmına bakarsak, enum elemanlarının bir indisinin olduğunu söyleyebiliriz.
Her elemanın bir indisi vardır ve ilk indis dizilerdeki gibi sıfır (0)'dan başlar.
Buna bir örnek verelim.
1 //Enum6.java - 07.04.2014
2
3 enum Arabalar5
4 {
5
AUDI, MERCEDES;
6 }
7
8 public class Enum6
9 {
10 public static void main(String[] args)
11 {
12
System.out.println(Arabalar5.AUDI.ordinal());
13
System.out.println(Arabalar5.MERCEDES.ordinal());
14 }
15}
16
17
Ekran çıktısı:
1
0
2
1
Ordinal() metodu ile enum elemanlarının indisini öğrenebiliriz.
Enum elemanlarının bir indisi olduğunu söylemiştik. Bu indisi bulmayı
öğrendik. Şimdi bu indisi kullanarak da bir örnek yapalım. Bu örneği
yaparken switch yapılarını da kullanacağız. Bu da demek oluyor ki enum
elemanları switch içerisinde bulunabilir.
//Enum7.java - 07.04.2014
1
2
enum aylar
3
{
4
ocak, subat, mart // sona noktalı virgül
5
gelmeyebilir
6
}
7
8
public class Enum7
9
{
10
public static void main(String[] args)
11
{
12
int x = aylar.mart.ordinal(); // mart ayının indisi
13
alındı
14
switch(x)
15
{
16
case 0: System.out.println("Ocak ayındayız");
17
break;
18
case 1: System.out.println("Şubat ayındayız");
19
break;
20
case 2: System.out.println("Mart ayındayız");
21
break;
22
default: System.out.println("Bu aylarda değiliz");
23
break;
24
}
25
}
26
}
27
Ekran çıktısı:
1
Mart ayındayız
Aylar adında bir enum tanımladık ve elemanlarını belirledik. Ordinal metodu
ile Mart ayının indisini bir xdeğişkenine attık. Daha sonra
bildiğiniz switch yapısı ile bunu karşılaştırdık.
ENUM İÇERİSİNDE METOD TANIMLAMA
Enum içerisinde değişken ve yapıcı tanımlamayı gördük. Şimdi de enum
içerisinde metod tanımlamayı görelim. Enum içerisinde metodlar da
tanımlanabilir.
1 //Enum8.java - 07.04.2014
2
3 enum Maaslar
4 {
5
Okan(1000), Onur(1200), Göksu(2000);
6 private int maas;
7
Maaslar(int m)
8
{
9
maas = m;
10 }
11 int maasGoster()
12 {
13
return maas;
14 }
15 static void metod2()
16 {
17
System.out.println("Burası metod2'dir");
18 }
19}
20
21public class Enum8
22{
23 public static void main(String[] args)
24 {
25
System.out.println(Maaslar.Okan.maasGoster());
26
System.out.println(Maaslar.Onur.maasGoster());
27
System.out.println(Maaslar.Göksu.maasGoster());
28
Maaslar.metod2();
29 }
30}
31
32
Ekran çıktısı:
1
1000
2
1200
3
2000
4
Burası metod2'dir
Enum içerisinde 2 farklı metod tanımladık. Birisi maaşları döndürüyor diğeri
ise ekrana bir String yazıyor.main metodunda ise, bu metodları
çağırdık. Metod2'ye main içerisinden erişebilmek için static olarak tanımladık.
Ders 56 - Annotation Kavramı
Annotation kavramı ilk olarak Java 5 ile karşımıza çıkmıştır. Annotation, Java
koduna eklenebilen sınıf, metod, değişken, parametre ve paketlere ön
bilgi ve metadata eklemek için kullanılan yapılardır. Annotation'lar üç şekilde
kullanılabilir. Bunlar:

Derleyici bilgilendirme için kullanılabilir. Bu tip kullanılan
annotation'lar sayesinde derleyici hataları ve uyarıları görmezden gelir.

Derlenme ve yüklenme anında kullanılarak otomatik kod ve XML
dosyası oluşturma gibi işlemlerde kullanılabilirler.

Çalışma anında işletilerek kodun annotation'a göre çalışması sağlanır.
Annotation'lar başına @ işareti yazılarak kullanırlar. Her durumda
annotation'lar bilgilendirilmek istenilen nesneden önce gelmelidir. Bazı
annotation'lar derleyici ön tanımlı durumdadır. Bazı metodları kullandığımızda
derleyicinin annotation ile sağladığı uyarıyla karşılaşabiliriz.
Örneğin;

@Override: Miras alınan sınıf içerisindeki bir metodu, alt sınıfta
yeniden tanımlamak istediğimizde, derleyici bize bunu annotation ile
bildirir.
@Override
1
void metod()
2
{
3
// metod
4
gövdesi
5
}

@Deprecated: Sürümü eski olan metodlar kullanıldığında, derleyici
bizi bu annotation ile uyarır.
1
@Deprecated
2
static void main()
3
{
4
5

// metod gövdesi
}
@SuppressWarnings: Bu annotation tipi, parametre olarak
vereceğimiz uyarı tipini derleyicinin göz ardı etmesini sağlar.
1
@SuppressWarnings("karşı koyma")
2
void metod()
3
{
4
// metod gövdesi
5
}
ANNOTATION OLUŞTURMA
Java'daki annotation'lar, sadece derleyicinin bize sunduğu annotation'larla
sınırlı değildir. Kendimiz özel durumlar için annotation yazabiliriz. Annotation
yazmak, interface yazmaya benzer. Annotation'umuzu
yazarken @interface anahtar kelimesi ile işaretlemeliyiz. Örnek bir annotation
tanımı aşağıdaki gibi olacaktır.
public @interface
1
annotationOrnegi
2
{
3
// metod gövdesi
4
}
Bu, tüm birimler için annotation tanımına örnektir. Eğer annotion'u bir birim ile
sınıflandırmak istiyorsak, annotation'dan önce @Target anahtar kelimesini ve
bunun tipini yazmalıyız. Aşağıda @Target anahtar kelimesinin tipleri
verilmiştir.

@Target(ElementType.TYPE): Sadece sınıf, enum ve interface için
sınırlanır.

@Target(ElementType.PACKAGE): Sadece paketler için
sınırlandırılır.

@Target(ElementType.METHOD): Sadece metodlar için
sınırlandırılır.

@Target(ElementType.LOCAL_VARIABLE): Sadece yerel
değişkenler için sınırlandırılır.

@Target(ElementType.CONSTRUCTOR): Sadece yapıcı metod
için sınırlandırılır.

@Target(ElementType.FIELD): Sadece sınıf üyeleri için
sınırlandırılır.

@Target(ElementType.ANNOTATION_TYPE): Sadece annotation
birimleri için tanımlanan annotation sınırlandırılır.
Annotation yazarken bir diğer belirteceğimiz unsur ise, derleyicinin derleme ve
çalışma anında annotation'a erişip erişemeyeceği unsurdur. Bunu belirtirken;
aynen @Target anahtar kelimesi olduğu gibi annotation'dan
önce @Retentation anahtar kelimesi ve tipini yazmamız gerekir. Derleyicinin
derleme anında annotation'a erişmesini istiyorsak, aşağıdaki anahtar kelimeyi
annotation'dan önce yazmalıyız.
1
@Retention(RetentionPolicy.RUNTIME)
Tüm bu gördüklerimizi bir örnek üzerinden kısaca anlatmaya çalışalım.
1 //annotationOrnegi.java - 07.04.2014
2
3 import java.lang.annotation.ElementType;
4 import java.lang.annotation.Retention;
5 import java.lang.annotation.RetentionPolicy;
6 import java.lang.annotation.Target;
7
8 @Target(ElementType.TYPE)
9 @Retention(RetentionPolicy.RUNTIME)
10 @interface geoBilgi
11 {
12
public String sekilIsmi();
13
public int kenarSayisi();
14 }
15 @geoBilgi (sekilIsmi = "Düzgün Sekizgen", kenarSayisi = 8)
16 class geometrikSekil
17 {
18
public int icAci(int kenar)
19
{
20
return (180*(kenar - 2)) / kenar;
21
}
22
public int kosegenSayi(int kenar)
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
return (kenar*(kenar - 3)) /2;
}
}
public class annotationOrnegi
{
public static void main(String args[])
{
geometrikSekil g = new geometrikSekil();
geoBilgi annotation = g.getClass().getAnnotation(geoBilgi.class);
// annotation bilgilerimizi oluşturduğumuz nesne içerisine aldık.
int aci = g.icAci(annotation.kenarSayisi());
// kenar sayısını annotation içerisinden aldırarak geometrik şeklimizin
iç açısını bulduk.
int kosegen = g.kosegenSayi(annotation.kenarSayisi());
// yine kenar sayısını annotationdan alarak köşegen sayısını bulduk.
System.out.println(annotation.sekilIsmi() + " : ");
System.out.println("Bir iç açısı = " + aci);
System.out.println("İçerisinden geçen toplam köşegen sayısı = " +
kosegen);
}
}
Ekran çıktısı:
Düzgün Sekizgen :
1
Bir iç açısı = 135
2
İçerisinden geçen toplam köşegen sayısı
3
= 20
Örneğimizde ilk aşamada bir annotation tanımladık. Bu annotation, geometrik
şeklimizin ismini ve kenar sayısını tutuyor. Derleyicinin derleme anında
ulaşabilmesi için @Retention ve annotation'un sadece sınıflar ile
sınırlandırmak için @Target anahtar kelimesini kullandık. Daha
sonrasında geometrikSekil sınıfımızı tanımlamadan önce sınıfımıza
oluşturduğumuz annotation'u ekledik. Bütün annotation'ları elde etmek
içingetAnnotation() metodunu kullandık. Böylelikle aynı türden birden fazla
annotation olması durumunda annotation'ları bir arada toplayabiliriz.
Köşegenimizin bir iç açısını hesap edebilmek için nesnemizin metoduna
parametre olarak annotation'dan aldığımız bilgiyi gönderdik ve geometrik
şeklimizin bir açısını elde ettik. Bu işlemlerin aynısını köşegen sayısını bulmak
için bir daha tekrar ettik ve köşegen sayısını elde ettik. Daha sonra bu bilgileri
ekrana yazdırdık.
Ders 57 - Garbage Collector (Çöp Toplayıcı)
Java dilinin üstünlüklerinden biri de Garbage Collection yapıcısının
bulunmasıdır. Programlarda bazı nesnelerin kullanımı bittiğinde bellekten
silinmeleri gerekir. C++ dilinde bu işi kendimiz yapıyorduk, fakat Java'da
otomatik olarak yapılıyor.
Bir nesneye programda bir referans verildiğini düşünelim. Mesela;
1
Hayvan h;
Burada new anahtar kelimesini kullanmadığımız için hnesnesi bellekte bir yer
kaplamaz. Ona sadecereferans verilmiştir. Bu şekilde programda olan
nesnelerin silinmeleri gerekir.
Java, dediğimiz gibi bu işi otomatik olarak yapar. Belirli aralıklarla programı
kontrol edip, işi bitmiş ve işaret edilmemiş nesneleri siler. Kullanılmayan bu
nesneler uygulamanın performansını da etkiler. Bu şekilde biriken nesneler,
programda OutOfMemoryException hatası verir. Eğer bir
nesne new operatörü ile oluşturulup belleğe yerleşmek ister ve bellekte de yer
kalmamış olursa, Garbage Collector hemen bellekteki gereksiz nesneleri
silerek yer ayırır. Nesneler, belleğin heap alanında toplandığı için Garbage
Collector bu alanda işlem yapar. Çöp toplama isteğini JVM'e gönderir.
Mükemmel bir algoritmaya sahip olan Garbage Collector, Java dilinin önemli
artılarındandır.
Kullanmayan nesneleri temizleyerek o alanı belleğe tekrar iade
eden bu Garbage Collector, otomatikolarak çalışır. Fakat bunu manuel, yani
kendimiz çalıştırmak istiyorsak; şu kod satırını kullanmamız gerekir.
1
Runtime. getRuntime.gc();
Veya
1
System.gc();
Eğer uygulamamızda gereksiz nesneler bulunmuyorsa, Garbage
Collector devreye girmez. Yukarıdaki kodlardan birini yazarak Çöp Toplayı'yı
etkin hale getirebiliriz.
FINALIZE METODUNUN KULLANIMI
Java'da bir nesneyi silmek istediğimizde ek olarak çalışan bir metod daha
vardır. Bu metod finalize()metodudur. Garbage Collector, nesneleri silmeden
önce bu metodu çağırır ve kullanır. Dolayısıyla nesneyi silerken yapmak
istediğimiz şeyler bu metod ile yapılır.
//GarbageCollector.java - 07.04.2014
1
2
public class GarbageCollector
3
{
4
GarbageCollector()
5
{
6
System.out.println("Nesne oluşturuldu");
7
}
8
protected void finalize()
9
{
10
System.out.println("Nesne silindi. Silinirken bu metod
11
çalıştı");
12
}
13
public static void main(String args[])
14
{
15
for(int i = 0 ; i < 3 ; i++)
16
{
17
GarbageCollector n1 = new GarbageCollector();
18
}
19
Runtime.getRuntime().gc(); // JM, Garbage Collector'u
20
çağırdı
21
}
22
}
23
Ekran çıktısı:
Nesne oluşturuldu
Nesne oluşturuldu
1
Nesne oluşturuldu
2
Nesne silindi. Silinirken bu metod
3
çalıştı
4
Nesne silindi. Silinirken bu metod
5
çalıştı
6
Nesne silindi. Silinirken bu metod
çalıştı
Garbage Collector, JVM tarafından çağırılır ve kontrol edilir. Bu örnekte 3
nesne oluşturduk ve Garbage Collector'u çağırdık. Bu da finalize() metodunu
işlenmek üzere çağırdı ve bu metod içerisindeki işlendi. Bu
metodun Protected olmasının sebebi; bu sınıfın dışından bu metoda
erişilememesi ve nesnelerin dışarıdan yok edilememesi gerekliliğidir.
Istisnalar:
!
Nesnelerin silinme sırası, oluşturulma
sıralarının tam tersidir. İlk oluşturulan
nesne en son silinir.
Istisnalar:
Dosya okuma yazma işlemlerinde
de Stream kullanarak bir işlem yaptığımızda o
Stream'ı kapatmak için definalize() metodu
! kullanılır. Okuma yazma işlemi için oluşturulan
nesneler, finalize() metodu ile bellekten
silinirler. Diyelim ki işlemleri o1 nesnesi ile
yaptık. o1.finalize(); diyerek nesneyi
silebiliriz.
super.finalize() ile üst sınıfın finalize() metodu çağırılabilir.
1
//Calistir.java - 07.04.2014
2
3
class A
4
{
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
A()
{
System.out.println("A sınıfından nesne
oluştu");
}
protected void finalize()
{
System.out.println("Burası A'nın finalize
metodu");
}
}
class B extends A
{
protected void finalize()
{
System.out.println("Burası B'nin finalize
metodu");
}
B()
{
super.finalize();
System.out.println("B sınıfından nesne
oluştu");
}
}
public class Calistir
{
public static void main(String args[])
{
B nesne1 = new B();
Runtime.getRuntime().gc();
}
}
Ekran çıktısı:
1
A sınıfından nesne oluştu
2
Burası A'nın finalize metodu
3
B sınıfından nesne oluştu
nesne1 adında bir nesne oluşturduk ve B sınıfının yapıcısı çalıştı. Üst sınıftan
türetildiği için doğrudan ilk olarak A sınıfının yapıcısı çalışmış oldu. Daha
sonra üst sınıfın finalize() metodunun çalışmasını istedik
ve Asınıfının finalize() metodu çalıştı. Bundan sonra ise B'nin yapıcısındaki
metin ekrana yazıldı. Bu işlemlerden sonra da Garbage Collector'u çağırdık ve
gereksiz nesneler varsa temizlenmesini istedik.
Garbage Collector yapısı ve finalize() metodu genel olarak bu şekildedir.
Istisnalar:
Bu bölümden sonra Kalıtım, Soyut Sınıflar,
! Arayüzler, Çok Biçimlilik gibi Nesneye
Yönelik Programlamanın temek
kavramlarını inceleyeceğiz.
Ders 58 - Kalıtım Kavramına Giriş
Nesneye yönelik programlamanın temel taşlarından biri olan Kalıtım,
sınıflardan yeni sınıflar türetmeyi sağlar. Türetilen bu yeni sınıflar, türetildiği
sınıfların özelliklerine sahip olur. Örneğin; Araç adında bir sınıfımız
olsun. Otomobil sınıfını bu Araç sınıfından türettiğimiz
zaman Otomobil sınıfı, Araç sınıfının özelliklerini taşır. Aynı
şekilde Hayvan adında bir sınıfımız olsun. Sürüngenler adında bir sınıfı
bu Hayvan sınıfından türetirsek,Hayvan sınıfını genişletmiş oluruz
ve Sürüngenler sınıfı, Hayvan sınıfının özelliklerini taşımış olur. Fakat bunun
tersi doğru değildir. Hayvan sınıfı, Sürüngenler sınıfının her özelliğini
taşımayabilir.
Kalıtım yapmak için kullanacağımız kelime extends'dir.
Şimdi Hayvan sınıfından Surungenler sınıfını türetelim.
public class Hayvan
1
{
2
}
3
public class Surungenler extends
4
Hayvan
5
{
6
}
Bu şekilde tanımlama yaptığımızda Surungenler sınıfındaki
elemanlar, Hayvan sınıfının elemanlarını miras
almış oluyor. Hayvan sınıfından extends ile bir sınıf daha oluşturabiliriz, fakat
bir sınıfı hem Hayvan hem deMemeliler sınıfından türetemeyiz. Yani bir
sınıf, birden fazla sınıftan türetilemez.
Surungenler sınıfı, Hayvan sınıfının elemanlarını miras aldığı
zaman, Hayvan sınıfındaki aynı olan özellikleri tekrar tanımlamasına gerek
kalmaz. Kalıtımın amacı da budur zaten. Bunun yanında Hayvansınıfından
aldığı metod ve değişkenlere başka metod ve değişkenler de ekleyebilir.
Eğer biz Surungenler adlı bir sınıf oluşturacaksak, aynı metodları tekrar
yazmak yerine Hayvan sınıfını miras alırız. Eğer ekleyeceğimiz farklı metodlar
varsa da bunları Surungen sınıfına dahil ederiz.
Şimdi kalıtım konusunda ilk örneğimizi verelim.
Hayvan Sınıfı:
//Hayvan.java - 07.04.2014
1
2
public class Hayvan
3
{
4
public void nefesAl()
5
{
6
System.out.println("Nefes alma
7
metodu");
8
}
9
}
10
11
Surungen Sınıfı:
//Surungen.java - 07.04.2014
1
2
public class Surungen extends Hayvan // Surungen sınıfını Hayvan sınıfından
3
türettik
4
{
5
public static void main(String[] args)
6
{
7
Surungen s = new Surungen();
8
s.nefesAl(); // artık bu sınıfımız da nefesAl metoduna sahip oldu
9
}
10
}
11
12
Ekran çıktısı:
1
Nefes alma metodu
Burada Surungen sınıfını Hayvan sınıfından türettik ve Surungen sınıfı
içerisinde, nefesAl() metodunu tanımlamadan bu metoda erişebildik.
Istisnalar:
! Kalıtımın en büyük avantajı bizi, üst sınıflarda
tanımlanmış olan metod ve değişkenleri tekrar
tekrar yazmaktan kurtarmasıdır.
Ders 59 - Super Class ve Sub Class Kavramları
SUPER CLASS (ÜST SINIF) VE SUB CLASS (ALT SINIF)
KAVRAMLARI
Kalıtım konusuna bir başka somut örnek verelim ve bununla birlikte bir
kavramı daha açıklayalım.Otomobil adında bir sınıfımız olsun. Yarış
otomobili ve aile otomobili sınıfları, Otomobil sınıfının alt sınıflarıdır (Sub class). Otomobil sınıfı da diğer bu sınıfların üst sınıfıdır (Super - class).
Otomobil örneğinde alt sınıflar, üst sınıfının tüm özelliklerine sahiptir. Bir
yarış otomobili, otomobilsınıfındaki vites ve hız gibi değişkenlere ve bunun
gibi metodlara sahip olur. Bunların yanında kendine ait metod ve değişkenleri
de olabilir. Bir yarış otomobilinde normal otomobilden farklı olarak ek
özellikler de bulunabilir. Bu ek özellikleri kendi sınıfına dahil edebilir. Bunun
dışında yarış otomobili sınıfı, Otomobilsınıfındaki freneBas adlı bir metodu
değiştirebilir. Buna metod overriding denir. Bunu ileriki konularda göreceğiz.
Istisnalar:
!
1
2
3
4
Kalıtım ve üst sınıf - alt sınıf konusuna bir örnek
daha verelim.
//Calistirma.java - 06.04.2014
class Telefon
{
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public Telefon()
{
System.out.println("Telefon sınıfının yapıcısı");
}
}
class AkilliTelefon extends Telefon
{
public AkilliTelefon()
{
System.out.println("AkilliTelefon sınıfının
yapıcısı");
}
}
class CepTelefonu extends Telefon
{
public CepTelefonu()
{
System.out.println("CepTelefonu sınıfının
yapıcısı");
}
}
class Nokia extends CepTelefonu
{
public Nokia()
{
System.out.println("Nokia sınıfının yapıcısı");
}
}
public class Calistirma
{
public static void main(String[] args)
{
Nokia n1 = new Nokia();
}
}
Ekran çıktısı:
1
Telefon sınıfının yapıcısı
2
CepTelefonu sınıfının yapıcısı
3
Nokia sınıfının yapıcısı
Bu örneğimizde Calistirma sınıfındaki main metodunda, Nokia sınıfından
bir nesne ürettik. Nokia sınıfı,CepTelefonu sınıfından
türetilmiştir. CepTelefonu sınıfı ise Telefon sınıfından türetilmiştir. En
yukarıdan başlayarak yapıcılar çağırılır ve en sonda ise ilk
oluşturulan nesnenin olduğu sınıfın yapıcısı çağırılır. Bir sınıftan nesne
oluşturulduğunda, o sınıfın yapıcısından önce, türetildiği sınıfın
yapıcısı çağırılır. Bu şekilde en üst seviyedeki SuperClass'ın yapıcı metodu
çağırılır.
Bir örnek daha verelim.
1
//Kalitim.java - 06.04.2014
2
3
class Sinif1
4
{
5
int x;
6
void metod1()
7
{
8
System.out.println("Burası metod1");
9
}
10
}
11
12
class Sinif2 extends Sinif1 // kalıtım yapıldı
13
{
14
int y;
15
void metod2()
16
{
17
System.out.println("Burası metod2");
18
}
19
}
20
public class Kalitim
21
{
22
public static void main(String[] args)
23
{
24
Sinif2 s2 = new Sinif2(); // Sinif2'den türetildi
25
s2.x = 7;
26
System.out.println(s2.x);
27
s2.metod1();
28
Sinif1 s1 = new Sinif1(); // s1.metod2(); bu metoda
29
erişilemezdi
30
}
31
}
32
Ekran çıktısı:
1
7
2
Burası metod1
Bu örnekte de Sinif2'den türetilen nesne ile Sinif1'in elemanlarına
erişebiliyoruz. Eğer Sinif1'den bir nesne oluştursaydık, bu nesne ile Sinif2'nin
elemanlarına erişemezdik.
Bir de metodlara parametre geçirelim ve türetilmiş sınıf üzerinden bu metodlara
erişelim.
1
//Kalitim2.java - 06.04.2014
2
3
class Sinif1_2
4
{
5
int x, y;
6
void degerAta (int a, int b)
7
{
8
x = a;
9
y = b;
10
}
11
}
12
13
class Sinif2_2 extends Sinif1_2 // kalıtım
14
yapıldı
15
{
16
int carp()
17
{
18
return x * y;
19
}
20
}
21
public class Kalitim2
22
{
23
public static void main(String[] args)
24
{
25
Sinif2_2 s2 = new Sinif2_2();
26
s2.degerAta(5, 9);
27
System.out.println(s2.carp());
28
}
29
}
30
Ekran çıktısı:
1
45
Sinif2_2'yi Sinif1_2'den türettik ve main metodunda Sinif2_2'den
oluşturduğumuz nesne ile Super Class olan Sinif1_2'nin degerAta metodunu
çağırdık. Bu metoda 5 ve 9 değerlerini gönderdik. Bu
parametreler, x ve t değişkenlerine atandı. Daha sonra s2 nesnesi
üzerinden carp metodunu çağırdık. Bu metod da, değerlerini
atadığımız x ve y değişkenlerini çarparak geriye sonucu döndürdü.
Peki, bu şekilde türetilen bir sınıf, türediği sınıfın her elemanına erişebilecek
mi? Eğer Super Class'daprivate elemanlar varsa sub class'lardan erişilemez.
Buna bir örnek verelim.
//Kalitim3.java - 06.04.2014
1
2
class Sinif1_3
3
{
4
private int x = 6; // private eleman
5
}
6
7
class Sinif2_3 extends Sinif1_3 // kalıtım
8
yapıldı
9
{
10
public String ad = "Okan";
11
}
12
public class Kalitim3
13
{
14
public static void main(String[] args)
15
{
16
Sinif2_3 s2 = new Sinif2_3();
17
System.out.println(s2.x); // hata verir
18
}
19
}
20
21
Ekran çıktısı:
1
Exception in thread "main" java.lang.Error: Unresolved compilation
2
problem:
3
4
The field Sinif1_3.x is not visible
at Kalitim3.main(Kalitim3.java:17)
Görüldüğü
gibi Sinif1_3'in private elemanlarına
erişemeyiz.
Ders 60 - Super Metodu ile Üst Sınıfın Yapıcısını Çağırmak
Kalıtım ile bir sınıftan başka bir sınıf türetmeyi ve bunları kullanmayı önceki
derslerimizde gördük. Bu dersimizde de farklı bir kavramdan bahsedeceğiz.
Türetilen sınıf, türeyen sınıfın yapıcısına ulaşmak isterse ne yapmak gerekir?
Bunun için super anahtar kelimesini kullanmalıyız. Bu anahtar kelimeyi
kullanarak üst sınıfın yapıcısını çağırmak için super() metodunu çağırabiliriz.
A sınıfından B sınıfını türettik diyelim. Bu B sınıfının yapıcısının
içerisinde super() metodunu çağırırsak, Asınıfının yapıcısı çağırılmış olur.
Istisnalar:
!
Alt sınıftaki yapıcının içerisinde ilk olarak super() metodu
yazılmalıdır. Bu alt sınıftaki yapıcıda ekrana yazdırma, başka bir
metod çağırma gibi işlemler de olabilir. super() metodu, bunlardan
önce ilk sırada yazılır.
super() ile üst sınıfın yapıcısı çağırılacaksa ve bu üst sınıftaki yapıcılar da
birden fazla ise hangisinin çağırılacağına şöyle karar verilir. super() metodunun
parametrelerine, çağırılacak yapıcının parametreleri yazılır. Parametreleri
eşleşen yapıcı çağırılır.
Buna bir örnek verelim.
1
//B.java - 07.04.2014
2
3
class A
4
{
5
public A() // A'nın yapıcısı
6
{
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
System.out.println("A'nın
yapıcısı");
}
}
class B extends A
{
public B() // B'nin yapıcısı
{
super(); // A'nın yapıcısı çağırıldı
System.out.println("B'nin
yapıcısı");
}
public static void main(String[]
args)
{
B nesne = new B();
}
}
Ekran çıktısı:
1
A'nın yapıcısı
2
B'nin yapıcısı
Bu örnekte B'nin yapıcısında ilk olarak super() metodu ile üst sınıfın yapıcısını
çağırdık. Yapıcılarda ilk olarak bunu çağırmamız zorunludur. super() ile
çağırdığımız zaman A'nın yapıcısı çağrıldı. main metodumuzda da B sınıfından
bir nesne oluşturduk. Bu ilk olarak B'nin yapıcısını çağırdı ve program
anlattığımız şekilde çalıştı.
Şimdi de A sınıfında birden fazla yapıcımız olsun. Yani yapıcılar aşırı
yüklenmiş olsun (overloading). Buna bir örnek verelim.
1
//B2.java - 07.04.2014
2
3
class A2
4
{
5
public A2(int a)
6
{
7
System.out.println("Tek parametreli yapıcı: " + a);
8
}
9
public A2(int a, int b)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
System.out.println("İki parametreli yapıcı: " + a + " ve
" + b);
}
}
class B2 extends A2
{
public B2()
{
super(4, 7); // ikinci parametreli yapıcı çağırıldı
System.out.println("B'nin yapıcısı");
}
public static void main(String[] args)
{
B2 nesne = new B2();
}
}
Ekran çıktısı:
1
İki parametreli yapıcı: 4 ve 7
2
B'nin yapıcısı
A sınıfımızda 2 adet constructor (yapıcı) var. Birisi 1, diğeri 2 parametre
alıyor. B sınıfını da A'dan türettik. Daha sonra B sınıfının yapıcısında 2
parametreli yapıcıyı çağırdık ve 2 adet int değerini gönderdik(super(4, 7). Eğer
tek parametreli yapıcıyı çağırmak isteseydik super metodu içerisine sadece bir
int değeri verirdik. Derleyici bunu otomatik olarak algılıyor ve super() metodu
içerisinde kaç parametre varsa, o parametrelere sahip yapıcı çağırılıyor.
Aşağıdaki örnekte ise yapıcılar içerisinde farklı işlemler
yaparak, super() metodu ile bu yapıcıyı çağıralım.
1
//B3.java - 07.04.2014
2
3
class A3
4
{
5
int x;
6
String ad;
7
public A3(int a, String b)
8
{
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
x = a;
ad = b;
}
public A3(String b, int a) // Çağırılan yapıcı budur
{
ad = b;
x = a;
}
void yazdir()
{
System.out.println("Değerler : " + ad + " ve " + x);
}
}
class B3 extends A3
{
public B3()
{
super("Okan", 7); // 1. parametresi String, 2. parametresi int olan
yapıcı çağırıldı
}
public static void main(String[] args)
{
B3 nesne = new B3();
nesne.yazdir();
}
}
Ekran çıktısı:
Değerler : Okan ve
1
7
Bu örnekte super("Okan", 7) ile ilk parametresi String ikinci
parametresi int olan yapıcıyı çağırdı ve gönderilen
değerleri ad ve x değişkenlerine yazdı. main metodunda oluşturduğumuz nesne
ile program çalışmaya başlayacaktır. B3 sınıfından bir nesne oluşturduğumuz
için B3 sınıfının yapıcısı çağırıldı. Daha
sonramain metodunda nesne.yazdir() diyerek A3 sınıfındaki yazdir metodunu
çalıştırdık ve atanmış olan değerleri yazdırdık.
super anahtar kelimesi ile ilgili söyleyeceğimiz son özellik de, bu kelimenin
aynı zamanda sınıftaki değişkenlere erişmeyi sağlamasıdır. Bu özelliği örnek
üzerinde anlatalım.
//AltSinif.java - 07.04.2014
1
2
class UstSinif
3
{
4
int x;
5
}
6
class AltSinif extends UstSinif
7
{
8
int x;
9
public AltSinif(int i, int j)
10
{
11
super.x = i; // UstSinif'in x değişkenine
12
atar
13
x = j;
// AltSinif'in x değişkenine
14
atar
15
}
16
public static void main(String[] args)
17
{
18
AltSinif nesne = new AltSinif(3, 6);
19
}
20
}
21
main metodunda nesneyi oluşturduk ve yapıcısına 3 ve 6 değerlerini
gönderdik. AltSinif'in yapıcısında alınan i değeri super.x değişkenine atanır.
Hem üst sınıfta hem de alt sınıfta bu değişken var. Peki, hangisine atama
yapılıyor? Eğer super.x dersek üst sınıfın x değişkenine atama yapılır.
Alınan j değeri de normal xdeğişkenine atandı. Bu x değişkeni
de AltSinif sınıfındaki x değişkenidir.
Bu örnekte, super anahtar kelimesi ile üst sınıftaki değişkenlere
erişebileceğimizi gördük. Hatırlarsanızthis anahtar kelimesi de buna benzer bir
iş yapıyordu. Fakat super anahtar kelimesi, üst sınıfın elemanlarına erişmeyi
sağlarken, this ise bulunduğu sınıfın elemanlarına erişmeyi sağlıyordu.
super metodunun kullanım şekli böyledir. Bunun ile ilgili bilmemiz gereken en
önemli nokta, yapıcıların her zaman en üstünde tanımlanırlar.
Ders 61 - Metod Overriding
Kalıtım konusunda anlattığımız gibi, türetilen sınıf türediği sınıfın tüm
özelliklerini taşıyor ve kullanabiliyordu. Fakat miras aldığı bu metodları aynen
kullanmak istemezse, ne yapmamız gerekir? Buradaoverriding kavramı
karşımıza çıkıyor. Bir sınıf, türetildiği sınıftaki bir metodu değiştirmek istediği
zaman bunuoverriding ile gerçekleştiriyoruz. Bu şekilde
metodları override ettiğimiz zaman alt sınıf, üst sınıfın metodunu doğrudan
kullanmak yerine kendine ait bir metoda sahip oluyor.
Şimdi bir örnek verelim.
1
//SinifA.java - 07.04.2014
2
3
public class SinifA
4
{
5
protected int sayi = 6;
6
public String ad = "Okan";
7
public String metod()
8
{
9
return ad + sayi;
10
}
11
}
12
13
class SinifB extends SinifA
14
{
15
public String metod() // metod override edildi
16
{
17
return ad + sayi + ad;
18
}
19
}
20
21
class calistir
22
{
23
public static void main(String[] args)
24
{
25
SinifB n = new SinifB();
26
System.out.println(n.metod());
27
}
28
29
30
}
Ekran çıktısı:
1
Okan6Okan
Bu örnekte SinifB, SinifA'nın metodunu override ediyor. Artık kendine ait bir
metodu oldu. mainmetodunda bu SinifB içerisindeki metodu
çağırdığımızda, SinifA'nın değil SinifB'nin metodu çağırılıyor.
EğerSinifB içerisinde bir metod tanımlasaydık, doğrudan SinifA içerisindeki
metodu çalıştıracaktı. Onu da gösterelim.
//SinifA.java - 07.04.2014
1
2
public class SinifA
3
{
4
protected int sayi = 6;
5
public String ad = "Okan";
6
public String metod()
7
{
8
return ad + sayi;
9
}
10
}
11
12
class SinifB extends SinifA
13
{
14
// override edilen bir metod yok
15
}
16
17
class calistir
18
{
19
public static void main(String[]
20
args)
21
{
22
SinifB n = new SinifB();
23
System.out.println(n.metod());
24
}
25
}
26
27
Ekran çıktısı:
1
Okan6
Burada SinifB içerisinde bir metod yok. Daha doğrusu override edilen bir
metod yok. O yüzdenSinifB'den bir nesne oluşturduğumuzda ve bu nesne
üzerinden bir metod çalıştırdığımızda doğrudanSinifA'nın metodu çalışacaktır.
Kalıtım konusunda, alt sınıf üst sınıfın elemanlarını tekrar tanımlamak zorunda
kalmıyordu ve doğrudan kullanıyordu. Override ile istenilen metodlar tekrar
tanımlanabilir ve aynı kendine göre düzenleyebilir.
Istisnalar:
!
Bir metodun override edilebilmesi için belli başlı kurallar vadır. Her
metod override edilemez.
Notumuzda söylediğimiz gibi bu belli başlı kurallara bir değinelim. Nasıl ki
metodlar konusunda anlattığımız overload özelliği gibi override konusunda da
genel olarak aynı şeyler geçelidir.
1.
Override edilecek metodların dönüş tipi, metod adı, parametre
listeleri aynı olmak zorundadır.
2.
Alt sınıftaki override edilecek metodun erişim belirleyicisi, üst
sınıftaki override edilen metodun erişim belirleyicisinden daha yüksek
derecede olmalı.
İlk maddeyi Ders 33 - Metodları Aşırı Yükleme (Overloading) konusundan
biliyorum. Bunlardan bir tanesi farklı olduğu zaman override işlemi
yapılamıyor. İkinci maddeyi ise örneğimiz üzerinden anlatalım. Alt sınıftaki
metodumuzun erişim belirleyicisi public olarak tanımlanmıştır. Bu yüzden üst
sınıftaki aynı metodun erişim belirleyicisi, public'ten daha kısıtlı olmalıdır.
Eğer alt sınıftaki private olarak tanımlamış olsaydık üst sınıftaki
metod private ve private'den daha kısıtlı olmalıdır. private'den daha kısıtlı
olan yoktur. Mecburen üst sınıftakini de private tanımlamak zorunda kalırdık.
Override konusuna bir örnek daha verelim.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//A.java - 08.04.2014
class A
{
int x, y;
A(int i, int j) // A sınıfının yapıcısı
{
x = i;
y = j;
}
void yazdir()
{
System.out.println("x ve y değerleri: " + x + " " + y);
}
}
class B extends A
{
int z;
B(int i, int j, int k) // B sınıfının yapıcısı
{
super(i, j); // i ve j üst sınıfının yapıcısına gönderildi
z = k;
// alınan k değeri z'ye atandı
}
void yazdir(String yazi) // metod overriding
{
System.out.println(yazi + z);
}
}
class calistir
{
public static void main(String[] args)
{
B nesne = new B(6, 1, 8);
// B'den nesne oluşturulup ilk değer
ataması yapıldı
nesne.yazdir("Z'nin değeri: "); // B sınıfının yazdir() metodu çağırılır
nesne.yazdir();
// A sınıfının yazdir() metodu çağırılır
}
}
Ekran çıktısı:
1
Z'nin değeri: 8
2
x ve y değerleri: 6
1
Yazdığımız kodu açıklayalım.
1.
İlk olarak main metodundan başlayalım. B sınıfından nesne
oluşturduk ve parantezler içerisinde B'nin yapıcısına 3 değer
gönderdik. Bu değerlerden ilk ikisi, super() ile üst sınıfın yapıcısına
gönderildi. Gönderilen son değer ise z değişkenine atandı.
2.
Daha sonra nesne.yazdir() diyerek parametre olarak bir String değeri
gönderdik. Dolayısıyla Bsınıfındaki yazdir() metodu çalıştı. Normalde
böyle bir metod olmasaydı doğrudan A sınıfındaki metod çalıştırılırdı.
Fakat B sınıfı diyor ki, ben A'nın metodunu kullanmak istemiyorum
kendi metodumu oluşturdum.
3.
Son olarak nesne.yazdir() metodunu parametre göndermeden
çalıştırdık. B sınıfında böyle bir metod olmadığı
için default olarak A sınıfındaki yazdir() metodu çalıştırıldı.
Üst sınıfa override ettiğimiz metodu doğrudan çağırmak için super() metodunu
kullanabiliriz. Bir önceki örnekte bu metodu, üst sınıfın yapıcısına parametre
göndermek için kullanmıştık.
1 //A.java - 08.04.2014
2
3 class A
4 {
5
void yazdir()
6
{
7
System.out.println("Burası A sınıfı");
8
}
9 }
10
11 class B extends A
12 {
13
void yazdir()
14
{
15
super.yazdir(); // üst sınıftaki yazdir() metodu
16 çağırılır
17
System.out.println("Burası B Sınıfı");
18
}
19
20
21
22
23
24
25
26
27
28
29
}
class calistir
{
public static void main(String[] args)
{
B nesne = new B();
nesne.yazdir();
}
}
Ekran çıktısı:
Burası A
1 sınıfı
2 Burası B
Sınıfı
yazdir() metodunu override ettik ve B sınıfındaki yazdir() metodunun
içerisinde de üst sınıftaki yazdir() metodunu çağırdık.
Bu dersimizden sonra overloading ve overriding kavramlarını karıştırmış
olabilirsiniz. Bunu şöyle açıklayalım. Overriding'de metod
adı, parametreler, tipler aynı olmak zorundadır. Overloading'de
iseparametre sırası,tipleri veya sayısından en az biri farklı olmalıdır.
Metod overriding konusunun temel mantığı bu şekildedir. Bu konuyu
anlatırken super anahtar kelimesini de tekrar etmiş olduk.
TOSTRING METODUNUN OVERRIDE EDİLMESİ
toString() metodu, nesnelerin metin karşılıklarının ekrana yazılması için
kullanılır. toString metoduObject sınıfı altında tanımlanmıştır yani her
sınıf, toString() metoduna erişip bu metodu kullanabilir.
AncaktoString metodu her zaman yeterli değildir. Nesnenin metin karşılığı
yoksa toString() metodu, nesnenin sınıf ismini ve
hafızadaki referansını geriye döndürür.
Aşağıdaki örnek üzerinden bu durumu açıklayalım.
1
//toStringOrnegi.java - 08.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package toString;
class sekil
{
int kose;
int kosegen;
int icAci;
sekil(int kose)
{
this.kose = kose;
kosegen = (kose * (kose - 3)) / 2;
icAci = (180 * (kose - 2)) / kose;
}
}
public class toStringOrnegi
{
public static void main(String[] args)
{
sekil geometrik = new sekil(5);
System.out.println(geometrik);
//
System.out.println(geometrik.toString());
}
}
Ekran çıktısı:
1 toString.sekil@4f0e284f
Yukarıdaki örnekte geometrik şekil tanımlayabildiğimiz bir sınıf oluşturduk.
Daha sonrasında bu sınıftan bir nesne oluşturduk ve bu nesnenin metin
karşılığını almak için nesneyi println() metoduyla ekrana yazdırdık. Böyle bir
durumda Java sınıf içerisinde toString() metodunun override edilip
edilmediğini kontrol eder. Sınıf içerisinde toString() metodu yoksa ya da eğer
sınıf başka bir sınıfın alt sınıfıysa ve üst sınıfta toString()metodununun
kullanılıp kullanılmadığını kontrol edilir. En son durumda Java, hiçbir yerde bu
metodu bulamadığında Object sınıfında tanımlı olan
genel toString() metodunu kullanır. Bu durumda Java, nesneninsınıf ismini ve
hafızadaki referansını ekrana yazar.
Örneğimizde tanımladığımız sınıf
içerisinde toString metodunu override etmediğimiz için üst sınıfın
yaniObject sınıfının toString() metodu çağrıldı ve metodumuzun bilgileri
ekrana yazıldı. Burada toString.sekil()metodumuzun bulunduğu paket
adı ve sınıfımızın ismini gösterir. Daha sonrasındaki @ işaretinden sonraki
sayı ise metodumuzun bellekteki referansını gösterir. Dediğimiz gibi bir
sınıfta toString() metodu yoksa nesneyi yazdırmak istediğimizde dönen
değerler bu şekilde olur.
Istisnalar:
!
Eğer bir nesneyi ekrana
yazdırdığımızda Object sınıfındaki toString() metodunun
çalıştırılmasını ve yukarıdaki değerlerin döndürülmemesini
istemiyorsak, bu metodu override edip kendimize göre
düzenlemeliyiz.
toString() metodunu override ederek nesnelerimizin daha anlaşılır olmasını
sağlayabiliriz. Yukarıdaki örneği sınıf
içerisinde toString() metodunu override edecek şekilde yeniden düzenleyerek
bu konuyu açıklamaya çalışalım.
1 //toStringOrnegi.java - 08.04.2014
2
3 package toString;
4
5 class sekil
6 {
7
int kose;
8
int kosegen;
9
int icAci;
10
11
sekil(int kose)
12
{
13
this.kose = kose;
14
kosegen = (kose * (kose - 3)) / 2;
15
icAci = (180 * (kose - 2)) / kose;
16
}
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Override
public String toString() // toString metodu override edildi
{
return kose + " koşeli düzgün geometrik şeklin " + kosegen + " adet
köşegeni vardır. Bir iç açısı ise " + icAci + " derecedir.";
}
}
public class toStringOrnegi
{
public static void main(String[] args)
{
sekil geometrik = new sekil(8);
System.out.println(geometrik); // nesne yazdırılıyor
String s = "Sekizgen: " + geometrik;
System.out.println(s);
}
}
Ekran çıktısı:
8 koşeli düzgün geometrik şeklin 20 adet köşegeni vardır. Bir iç açısı ise
1
135 derecedir.
2
Sekizgen: 8 koşeli düzgün geometrik şeklin 20 adet köşegeni vardır. Bir
iç açısı ise 135 derecedir.
Örneğimizde bir önceki örnekten farklı
olarak toString() metodunu override ettik. Bu sayede nesnemize ait metin
bilgilerini metod üzerinden ekrana yazdırabildik. Örnekte görüldüğü
gibi toString() metodu, sadece nesne println() metodu ile yazdırılmak
istendiğinde çağrılmaz. toString() metodu nesne ile ilgili metin işlemleri
gerektiren yerlerde çağrılır. Yukarıdaki örnekte kendi metinimizle nesnemizin
döndüreceği metini birleştirdik ve bu anda toString() metodu çağrılmış oldu.
Şimdi başka bir örnek verelim. Bu örnekte
önce toString() metodunu override etmeden bir nesneyi yazdırmaya çalışalım.
1
//toStringOrnegi.java - 08.04.2014
2
3
package toString2;
4
5
class Calisan
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
public String ad = "Okan";
public String soyad = "Bilke";
public int yas = 23;
}
public class toStringOrnegi
{
public static void main(String[]
args)
{
Calisan kisi = new Calisan();
System.out.println(kisi);
}
}
Ekran çıktısı:
1 toString2.Calisan@324a4e31
Biz burada kisi nesnemizi yazdırmak istediğimizde, aslında tüm bilgilerinin
yazılmasını istedik. Fakat biz nesneyi yazdırmak istediğimizde biliyoruz
ki; Object sınıfının toString() metodu çalıştırılır ve bu metod dapaketadı
sınıfadı şeklinde değer döndürür.
Nesnemize ait olan değerleri yazdırmak için kendimiz biz toString() metodu
yazarak, Object sınıfındakitoString() metodunu override edelim.
1
2
3
4
5
6
7
8
9
10
11
//toStringOrnegi.java - 08.04.2014
package toString2;
class Calisan
{
public String ad = "Okan";
public String soyad = "Bilke";
public int yas = 23;
public String toString() // override işlemi
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
return "Ad: " + ad + " Soyad: " + soyad + " Yas: "
+ yas;
}
}
public class toStringOrnegi
{
public static void main(String[] args)
{
Calisan kisi = new Calisan();
System.out.println(kisi);
}
}
Ekran çıktısı:
1
Ad: Okan Soyad: Bilke Yas: 23
Sınıfımız içerisinde toString() metodunu override ederek, nesnemizi
yazdırmak istediğimizde nelerin yazılmasını istiyorsak, onu return ile ekleriz.
Ders 62 - Final Anahtar Kelimesi
Bu konuyu Değişkenler dersimizde kısaca anlatmıştık. Fakat Nesneye Yönelik
Programlama ve Kalıtımdahilinde detaylı olarak incelemeyi daha uygun
gördüm. Çünkü nesneye yönelik programlamada ve kalıtımda kullanılan bir çok
özelliği bulunuyor.
final anahtar kelimesi, Java'da temelde sabitler tanımlamaya yarar. Sabitler,
değeri sabit olan değişkenlerdir. Örneğin; Pi sayısının değeri bir sabittir.
Bunun dışında biz de istediğimiz bir değişkeni sabit olarak belirleyebiliriz.
Final anahtar kelimesini yalnızca değişkenlere
değil sınıflara, metodlara, parametre uygulayabiliriz. Dolayısıyla yalnızca
sabit tanımlama görevi yoktur. Bunları ayrı ayrı inceleyeceğiz.

Eğer bir sınıfı final olarak tanımlarsak bu sınıftan türetme yapamayız.

Bir metodu final olarak tanımlarsak bu
metodlar override edilemezler.

Bir parametreyi final olarak tanımlarsak bu parametrenin değerini
değiştiremeyiz.

Bir değişkeni final olarak tanımlarsak da değerini değiştiremeyiz.
FINAL İLE SABİT TANIMLAMA
final anahtar kelimesi ile tanımlanmış değişkenlerin değeri değiştirilemez.
Bunlara sabit değişkenler denir.(Sabitler)
final değişkenlerde söyleyeceğimiz ilk şey, final değişkenler ilk değeri
atanmadan kullanılamazlar. Normalde bir değişken tanımlanıp değeri
verilmediğinde default değere sahip olurdu. Fakat finaldeğişkenlerde bu
şekilde yaparsak hata ile karşılaşırız.
Buna bir örnek verirsek:
public final int x;
1
System.out.println(x); // hatalı kullanım. İlk değer atanmadan
2
kullanılamaz.
Şu şekilde tanımlama doğru olacaktır:
public class Insan
1
{
2
public final int x = 5; // final değişken tanımlandı ve ilk değeri
3
verildi.
4
}
final ile değişken tanımlamasında yanlış olan bir şey de değişkeni ilk değeri
olmadan tanımlıyoruz ve başka bir yerde ona değer veriyoruz. Bu
kullanım hatalıdır. Bu şekilde tanımlanmış değişkenlerin ilk değerleri,
tanımlandığı ilk anda ya da yapıcılar içerisinde verilmelidir. Fakat metodlar
içerisinde final tanımlarsak, başka satırda da ilk değeri verilebilir.
Tanımlandığı ilk anda değer vermeye örnek göstermiştir. Şimdi ise yapıcılar
içerisinde ilk değer almasına örnek verelim.
1
//FinalDegiskenler.java - 08.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class FinalDegiskenler
{
private final int x;
public final FinalDegiskenler (int deger) // yapıcı metod
tanımlandı
{
x = deger; // alınan parametre, final değişkenine atandı
}
public void yaz()
{
System.out.println(x); // final değişken ekrana yazdırıldı
}
}
Yapıcımız içerisinde, x adlı final değişkene ilk değerini atama işlemini yaptık.
Daha sonra main metodu içerisinde bir nesne oluşturup yaz() metodunu
çağırmamız gerekiyor.
final anahtar kelimesi ile tanımlanmış değişkenlerin değeri, programın herhangi
bir yerinde değiştirilemez. Buna da bir hatalı kullanım örneği verelim.
//Degiskenler.java - 08.04.2014
1
2
public class Degiskenler
3
{
4
private final int sayi;
5
public Degiskenler(int deger)
6
{
7
sayi = deger;
8
}
9
public static void main(String[]
10
args)
11
{
12
Degiskenler d = new
13
Degiskenler(5);
14
sayi = 10; // hatalı
15
}
16
}
17
Bu metoda bir nesne oluşturduk ve 5 değerini, yapıcı ile
atadık. sayi değişkenimiz 5 oldu. Daha sonra değişkenimizi 10 yapmaya
çalışıyoruz. Bu hatalı bir kullanımdır. Çünkü yapıcı ile sabit değişkenimize bir
değer verildi. Onu artık değiştirmeye çalışmak hata verecektir.
Final değişkenler, sınıf içerisinde tanımlandığı gibi metod içerisinde de
tanımlanabilir ve kullanılabilir. Eğer metod içerisinde tanımlarsak; ilk değer
atamasını, metod içerisinde başka satırlarda da yapabiliriz.
//Degiskenler2.java - 08.04.2014
1
2
public class Degiskenler2
3
{
4
public void al()
5
{
6
final int x; // metod içerisinde final
7
tanımlama
8
x = 5;
9
}
10
}
11
12
Eğer final değişkenleri, metod içerisinde tanımlarsak, diğerlerinden farklı
olarak ilk değer atamasını başka satırda da yapabiliriz, fakat bunu metod
içerisinde yapmak zorundayız.
Son olarak final değişkenler ile ilgili şundan bahsedelim. final değişkenler aynı
zamanda static olabilir. Yani sınıfa ait bir değişken olabilir. Tüm sınıf öğeleri
bu değişkeni ortam olarak kullanırlar ve değiştiremezler. Eğer böyle bir
değişken istiyorsak, yapmamız gereken tanımlama şu şekilde olacaktır:
1
public static final int x = 6;
Istisnalar:
!
final anahtar kelimesi ile yapacağımız tanımlamalarda değişken
isimlerini büyük yapmak, bu değişkeni diğerlerinden ayırdığı için
kodu okumada yarar sağlar.
FINAL İLE METODLARIN OVERRIDE EDİLMELERİNİ
ENGELLEME
Metodlar, final olarak tanımlanabilir. Değişkenlerdeki gibi sabit tanımlama
amacıyla kullanılmazlar. Yukarıda da bahsettiğimiz gibi metodları final olarak
tanımlarsak, bu metodlar override edilemezler.
Buna örnek vererek açıklayalım.
//FinalMetod.java - 08.04.2014
1
2
public class FinalMetod
3
{
4
public final void deneme() // final metod
5
{
6
System.out.println("Bu metod override edilemez");
7
}
8
}
9
10
public class FinalMetod2 extends FinalMetod
11
{
12
public final void deneme() // override edilemez
13
{
14
System.out.println("Bu metod override edilmeye
15
çalışıldı.");
16
}
17
}
18
19
Burada değiştirilmek istenen metod deneme() metodudur. Fakat bu
metod final olarak tanımlandığı için değiştirilemez.
final metodları, anlaşıldığı üzere alt sınıflardan değiştirilmesini
istemediğimiz metodlar için kullanılır. Yani override yapmamızı engeller.
FINAL İLE PARAMETRELERİN DEĞERİNİN DEĞİŞMESİNİ
ENGELLEME
final parametreleri, bir metoda gönderdiğimiz parametrelerin değişmesini
istemediğimiz durumlarda kullanırız. Diyelim ki bir metoda parametre
gönderiyoruz ve bu parametreyi kendi içinde tekrar eşliyoruz.
1
public void gonder()
2
{
3
int x = 5;
4
5
6
7
8
9
al(x);
}
public void al (final int y)
{
y = y + y;
}
Bu örnekte The final local variable y cannot be assigned. It must be blank
and not using x compound assignment hatası ile karşılaşacağız. Çünkü
parametre olarak aldığımız y değeri final olarak tanımlanmış yani sabit. Daha
sonra al() metodu içerisinde ise bu değerin 2 katını tekrar aynı değere atıyoruz.
Bu metod içerisindeki fonksiyon eğer int z = y + y; olsaydı, hata almayacaktık.
Çünkü alınan değer başka bir değişkene atandı, yani y'nin değeri değişmedi.
FINAL İLE SINIFLARIN KALITIMINI ENGELLEME
final anahtar kelimesi sınıflarda kullanılırsa, bir sınıf tanımlaması şu şekilde
yapılır.
public final class
1
Canli
2
{
3
}
Bu şekilde bir sınıf tanımlayabiliriz, fakat dediğimiz gibi bu sınıftan başka bir
sınıf türetemeyiz. Bu şekilde bir yanlış kullanıma örnek verelim.
1
public final class Canli
2
{
3
}
4
class Hayvan extends Canli // turetilemez
5
{
6
}
Burada Canli sınıfından Hayvan adlı bir sınıf türettik.
Fakat Canli sınıfımızı final ile tanımladığımız için bu kullanım şekli yanlıştır.
Başka bir örnek verelim.
1
//Sinif.java - 08.04.2014
2
3
final class Sinif
4
{
5
6
7
8
9
10
11
12
13
14
15
16
}
class SinifB extends Sinif // final class'tan kalıtım
yapılamaz
{
public static void main(String[] args)
{
SinifB s = new SinifB();
}
}
Ekran çıktısı:
Exception in thread "main" java.lang.Error: Unresolved compilation
1
problem:
2
3
at SinifB.main(Sinif.java:9)
Gördüğümüz gibi final olarak tanımlanmış sınıftan, başka bir sınıf türetemeyiz.
Bu kelime kalıtımı önler.
Ders 63 - Upcasting ve Downcasting Kavramları
Bu konuyu şu şekilde anlatalım. İlk olarak bir kalıtım ilişkisinin diyagramını
çizelim.
Burada bir kalıtım ilişkisi var. Yani her hayvan bir canlıdır. Aynı zamanda her
omurgalı da bir hayvandır. Aynı zamanda da tüm sınıflar Object sınıfından
türetilmişlerdir. Biz yukarda kalıtım ilişkimizi modelledik. Tüm sınıflar bir üst
sınıfını miras alıyor.
Şimdi aşağıda bu hiyerarşimizi kodlayalım.
1
//Canlı.java - 08.04.2014
2
3
class Canlı
4
{
5
public void adSoyle()
6
{
7
System.out.println("Burası Canlı sınıfı");
8
}
9
}
10
11
class Hayvan extends Canlı
12
{
13
public void adSoyle()
14
{
15
System.out.println("Burası Hayvan
16
sınıfı");
17
}
18
}
19
20
class Omurgalı extends Hayvan
21
{
22
public void adSoyle()
23
{
24
System.out.println("Burası Omurgalı
25
sınıfı");
26
}
27
}
28
29
class Omurgasız extends Hayvan
30
{
31
public void adSoyle()
32
{
33
System.out.println("Burası Omurgasız
34
sınıfı");
35
}
36
}
37
38
class Calistir
39
{
40
public static void main(String[] args)
41
42
43
44
45
46
47
48
49
50
{
Canlı c = new Canlı();
c.adSoyle();
Hayvan h = new Hayvan();
h.adSoyle();
Omurgalı o1 = new Omurgalı();
o1.adSoyle();
Omurgasız o2 = new Omurgasız();
o2.adSoyle();
}
}
Ekran çıktısı:
1
Burası Canlı sınıfı
2
Burası Hayvan sınıfı
3
Burası Omurgalı sınıfı
4
Burası Omurgasız sınıfı
Bu örnekte kalıtım ilişkimizin kodunu yazdık ve çıktısını inceledik. Her sınıfa
ait bir nesne oluşturduk ve ana sınıftaki adSoyle() metodunu override ettik.
Oluşturulan nesnelerin olduğu sınıftaki adSoyle() metodu çalıştı.
Biz sınıfımızda her hayvanın bir canlı olduğunu söyledik. Madem her hayvan
bir canlıdır, o zaman bizHayvan sınıfından bir nesne oluşturup bu
nesneyi Canlı sınıfının referansına bağlayabiliriz. Buna upcasting denir. Bunu
aynı örnek üzerinde gösterelim ve sadece Çalıştır sınıfımızı değiştirelim.
1
//Canlı.java - 08.04.2014
2
3
class Canlı
4
{
5
public void adSoyle()
6
{
7
System.out.println("Burası Canlı sınıfı");
8
}
9
}
10
11
class Hayvan extends Canlı
12
{
13
public void adSoyle()
14
{
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
System.out.println("Burası Hayvan
sınıfı");
}
}
class Omurgalı extends Hayvan
{
public void adSoyle()
{
System.out.println("Burası Omurgalı
sınıfı");
}
}
class Omurgasız extends Hayvan
{
public void adSoyle()
{
System.out.println("Burası Omurgasız
sınıfı");
}
}
class Calistir
{
public static void main(String[] args)
{
Canlı c = new Canlı(); // upcasting(1)
c.adSoyle();
Canlı h = new Hayvan(); // upcasting(2)
h.adSoyle();
Hayvan o1 = new Omurgalı(); //
upcasting(3)
o1.adSoyle();
Hayvan o2 = new Omurgasız(); //
upcasting(4)
o2.adSoyle();
}
}
Ekran çıktısı:
1
Burası Canlı sınıfı
2
Burası Hayvan sınıfı
3
4
Burası Omurgalı sınıfı
Burası Omurgasız sınıfı
Çıktımız yine aynı olacaktır. Çünkü biz kalıtıma aksi bir şey yapmadık.
Zaten her hayvan bir canlıdır. Her omurgalı da bir hayvandır. 2.
upcasting yapmamızda Hayvan sınıfından bir nesne oluşturduk ve bu nesneyi,
üst sınıfı olan Canlı sınıfının referansına bağladık. Diğer upcasting satırları da
bu şekildedir.
Aynı satırları şu şekilde de yazabilirdik:
1
//Canlı.java - 08.04.2014
2
3
class Canlı
4
{
5
public void adSoyle()
6
{
7
System.out.println("Burası Canlı sınıfı");
8
}
9
}
10
11
class Hayvan extends Canlı
12
{
13
public void adSoyle()
14
{
15
System.out.println("Burası Hayvan
16
sınıfı");
17
}
18
}
19
20
class Omurgalı extends Hayvan
21
{
22
public void adSoyle()
23
{
24
System.out.println("Burası Omurgalı
25
sınıfı");
26
}
27
}
28
29
class Omurgasız extends Hayvan
30
{
31
public void adSoyle()
32
{
33
System.out.println("Burası Omurgasız
34
sınıfı");
35
36
37
38
39
40
41
42
43
44
45
46
47
48
}
}
class Calistir
{
public static void main(String[] args)
{
Canlı c = new Canlı();
c.adSoyle();
Canlı h = (Canlı)new Hayvan();
h.adSoyle();
Hayvan o1 = (Hayvan)new Omurgalı();
o1.adSoyle();
Hayvan o2 = (Hayvan)new Omurgasız();
o2.adSoyle();
}
}
Yukarıda aslında aynı şeyi yaptık. Sadece referans olarak belirlediğimiz sınıfa
doğru cast işlemi yaptık.Upcasting yaparken bunu yapmak zorunlu değildir.
Fakat birazdan göreceğimiz Downcasting işleminde buzorunludur.
Peki, Downcasting işlemini nasıl yapıyoruz. Tahmin ettiğiniz gibi üst sınıfı, alt
sınıfın referansınabağlıyoruz. Bunu yaparken cast işlemi zorunludur. Yani
hangi sınıfın referansına bağladığımızı parantez içerisinde göstermemiz
gerekir. Aynı örneği bir de Downcasting için yapalım.
1
//Canlı.java - 08.04.2014
2
3
class Canlı
4
{
5
public void adSoyle()
6
{
7
System.out.println("Burası Canlı sınıfı");
8
}
9
}
10
11
class Hayvan extends Canlı
12
{
13
public void adSoyle()
14
{
15
System.out.println("Burası Hayvan sınıfı");
16
}
17
}
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Omurgalı extends Hayvan
{
public void adSoyle()
{
System.out.println("Burası Omurgalı
sınıfı");
}
}
class Omurgasız extends Hayvan
{
public void adSoyle()
{
System.out.println("Burası Omurgasız
sınıfı");
}
}
class Calistir
{
public static void main(String[] args)
{
Hayvan h1 = new Hayvan();
Canlı c = h1; // upcasting
Hayvan h2 = (Hayvan)c; //downcasting (1)
h2.adSoyle();
Omurgalı o1 = new Omurgalı();
Hayvan h3 = o1; // upcasting
Omurgalı o2 = (Omurgalı)h3; //
downcasting(2)
o2.adSoyle();
}
}
Ekran çıktısı:
Burası Hayvan sınıfı
1
Burası Omurgalı
2
sınıfı
Burada da downcasting örneği verdik. Yani üst sınıf, alt sınıfın tipinde referans
alması için zorlanıyor.Downcasting 1 işleminde Hayvan sınıfımızdan
türetilmiş olan nesne, bir alt sınıfı olan Omurgalı sınıfının referansına
bağlanıyor. Dolayısıyla oluşturulan o2 nesnesinin adSoyle() metodu
çalıştırılınca Hayvan sınıfının değil, Omurgalı sınıfının adSoyle() metodu
çalıştırılıyor. Dediğimiz gibi downcasting yaparken parantez içerisinde hangi
referansa işaret edileceği yazılmak zorundadır.
Kalıtımda alt sınıf, üst sınıfın üyelerine erişebiliyorken; üst sınıf, alt sınıfın
üyelerine erişemiyordu. Fakatdowncasting ile üst sınıfa ait bir referans ile alt
sınıftaki üyelere erişilebilir.
Ders 64 - Soyut Sınıflar ve Metodlara Giriş
Nesneye yönelik programlamada, sınıfları miras bırakırken bazı metodların
içeriğinin farklı olmasını isteyebiliriz veya bir üst sınıfa tanımladığımız ortak
metot, sınıfı miras bırakacağımız alt sınıfların bazılarının ihtiyacını
karşılamıyor olabilir. Bu gibi durumlarda soyut sınıfları kullanmak bizim için
avantaj sağlayacaktır.
Soyut sınıflarda amaç, nesne türetirken şablon oluşturmaktır. Soyut sınıfta
tanımlanan şablon, bu sınıfı miras alan alt sınıflarda override edilerek yeniden
tanımlanır. Örnek olarak üçgen, yamuk ve daire düşünelim. Örnek olarak
verdiğimiz nesnelerin ortak özellikleri ve birbirinden farklı oldukları bir takım
özellikler vardır. Hepsinin ortak özelliği bir geometrik şekil olmasıdır.
Farklarına ise basit olarak alan hesaplarını verebiliriz. Yani şekil isminde bir
sınıf tanımlasaydık bu sınıfı miras alacak üçgen, yamuk ve daire sınıfları için
alanı hesaplayabilecek ortak bir metod tanımlayamayacaktık. Bu tip örneklerde
üst sınıfı ve alt sınıflar için farklı olacak metodu, soyut tanımlarız. Alt
sınıflarda ise soyut tanımladığımız bu metodu override ederek yeniden
tanımlarız.
Soyut sınıf tanımladığımızda içerisinde mutlaka bir soyut metod
bulundurması gerekmektedir. Tersini düşündüğümüzde, yani sınıfın
içerisinde bir soyut metod tanımladığımızda ise, sınıfı soyut
işaretçisiyleişaretlemeliyiz(Sınıfı soyuta çevirmeliyiz). Bir sınıfı veya metodu
soyut olarak tanımlamak için erişim belirtecinden sonra abstract anahtar
sözcüğünü kullanmalıyız.
Soyut metodlar, kendi başına bir anlam ifade etmezler.
Istisnalar:
!
Bir metod soyut olarak tanımlandıysa, o metodun olduğu sınıf da
mutlaka soyut (abstract) olarak tanımlanmalıdır.
Istisnalar:
!
Soyut sınıftaki soyut metot, alt
sınıflarda override edilmezse, derleme anında hata ile karşılaşırız.
Ders 65 - Soyut Sınıf ve Kalıtm Arasındaki İlişki
Soyut sınıflar anlaşıldığı üzere Kalıtım konusuyla yakından ilişkilidir.
Kalıtımda olduğu gibi soyut sınıflarda da bu sınıftan bir sınıf türetiliyor ve
bazı gerekli metodlar override ediliyor.
Fakat bir fark var. Kalıtım konusunda alt sınıftayken, üst sınıfta
bulunan istediğimiz metodu overrideedebiliyorduk. Üst sınıftaki
metodumuzun başına override anahtar kelimesini getirerek, istediğimiz bir alt
sınıftan bu metotları override edebiliyorduk. Soyut sınıflarda, soyut olarak
tanımladığımız metot, alt sınıflardamutlaka override edilmelidir. Kalıtımdaki
gibi isteğe bağlı bir durum yoktur.
Soyut sınıflardan, soyut alt sınıflar türetilebilir. Bu şekilde türetirsek bu
alt soyut sınıf, üst soyut sınıfın soyut metodunu override etmek zorunda
kalmaz.
Bir başka fark da şudur: Kalıtım yaparken üst sınıfta tanımladığımız metot, o
üst sınıf için bir şeyler ifade ediyordu. Yani bu sınıfa ait bir metod oluyordu ve
bu üst sınıf bu metodu istediği gibi doldurarak kendisi için kullanabiliyordu. Bir
sınıfı soyut olarak tanımlayıp, içerisinde de soyut bir metod oluşturursak; bu
metodun o üst sınıf için bir anlamı olmaz. Sadece bu soyut sınıftan türeyen
sınıflar, bu metodu kullanarak kendileri için şekillendirirler. Yani bu soyut
metot, alt sınıfların işine yarar.
Soyut sınıfları kullanabilmek için kalıtım yapmamız gerektiği
için kalıtım ve soyut sınıflar konusu iç içedir.
Ders 66 - Soyut Sınıf Örneği
Bu dersimizi örnek üzerinden anlatalım.
//geometrikSekil.java - 08.04.2014
1
2
public abstract class geometrikSekil
3
{
4
private String isim;
5
6
public void isimBelirle(String isim)
7
{
8
this.isim = isim;
9
// geometrik şeklimizin ismini
10
belirledik
11
}
12
13
public String isimGetir()
14
{
15
return this.isim;
16
// şeklimizin ismini döndürecek
17
metod
18
}
19
20
// soyut metodumuzu tanımladık
21
public abstract double alanHesap();
22
}
23
Yukarıda görüldüğü gibi soyut sınıfımızı, abstract anahtar kelimesiyle
işaretleyerek tanımladık. Bu sınıfı miras alacak bütün sınıflar, tanımladığımız
soyut metodu override etmek zorundadırlar.
Metodumuzunoverride edilmemesi durumunda, aşağıdaki gibi hatayla
karşılaşacağız.
Şimdi bu sınıfı miras alacak diğer sınıfların tanımına geçelim.
ucgen.java
//ucgen.java - 08.04.2014
1
2
public class ucgen extends geometrikSekil
3
{
4
private double yukseklik;
5
private double taban;
6
7
public void bilgi(double yukseklik, double taban)
8
{
9
isimBelirle("Üçgen Nesnesi");
10
this.yukseklik = yukseklik;
11
this.taban = taban;
12
// üçgen nesnemizin bilgilerini belirledik
13
}
14
15
@Override
16
public double alanHesap()
17
{
18
return (taban*yukseklik) / 2;
19
// üçgenimizin alanını hesapladık ve bunu geriye
20
döndürdük
21
}
22
}
23
24
dikdortgen.java
1
//dikdortgen.java - 08.04.2014
2
3
public class dikdortgen extends geometrikSekil
4
{
5
private double uzunKenar;
6
private double kisaKenar;
7
8
public void bilgi(double uzunKenar, double kisaKenar)
9
{
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
isimBelirle("Dikdörtgen Nesnesi");
this.uzunKenar = uzunKenar;
this.kisaKenar = kisaKenar;
// dikdörtgen nesnemizin bilgilerini belirledik
}
@Override
public double alanHesap()
{
return uzunKenar * kisaKenar;
// dikdörtgenimizin alanını hesapladık ve bunu geriye
döndürdük
}
}
daire.java
//daire.java - 08.04.2014
1
2
public class daire extends geometrikSekil
3
{
4
private double yaricap;
5
private double pi = Math.PI;
6
7
public void bilgi(double yaricap)
8
{
9
isimBelirle("Daire Nesnesi");
10
this.yaricap = yaricap;
11
// daire nesnemizin bilgilerini belirledik
12
}
13
14
@Override
15
public double alanHesap()
16
{
17
return pi * Math.sqrt(yaricap);
18
// dairemizin alanını hesapladık ve bunu geriye
19
döndürdük
20
}
21
}
22
23
Yukarıdaki sınıflarda görüldüğü üzere soyut sınıfımızı miras aldık ve soyut
sınıfımızda tanımladığımız soyut metodumuzu, bu sınıfların
herbirinde override ettik. Daha önce soyut sınıfın tek başına
kullanılamayacağınıve soyut sınıfın kendini miras alan diğer sınıflar
için şablon olarak kullanılabileceğini söylemiştik. Peki, ana sınıfımızda soyut
sınıfımızdan bir nesne oluşturmak istersek ne olur? Cevabını aşağıdaki resim
üzerinden anlatalım.
Yukarıdaki şekilde de görüldüğü gibi soyut bir sınıfın nesnesini oluşturmak
istediğimizde hataylakarşılaşacağız. Derleyici bize "geometrikSekil'in bir
örneğini oluşturamazsınız" şeklinde bir uyarı veriyor.
Istisnalar:
!
Soyut sınıflardan nesne üretilemez, fakat alt sınıflardan bu soyut
sınıfa referans verilebilir. Ayrıca soyut sınıflar
içerisinde yapıcılar tanımlanabilir.
Örneğimizin son kısmıyla devam edelim.
1 //soyutSinifOrnegi.java - 08.04.2014
2
3 public class soyutSinifOrnegi
4 {
5
public static void main(String[] args)
6
{
7
daire daireNesnesi = new daire();
8
dikdortgen dikdortgenNesnesi = new dikdortgen();
9
ucgen ucgenNesnesi = new ucgen();
10
// nesnelerimizi oluşturduk
11
12
daireNesnesi.bilgi(5.0);
13
System.out.print(daireNesnesi.isimGetir() + ": ");
14
System.out.println(daireNesnesi.alanHesap());
15
// daire için alanı hesapladık
16
17
dikdortgenNesnesi.bilgi(5.0, 3.0);
18
System.out.print(dikdortgenNesnesi.isimGetir() + ":
19 ");
20
System.out.println(dikdortgenNesnesi.alanHesap());
21
// diktörtgen için alanı hesapladık
22
23
ucgenNesnesi.bilgi(4.0, 3.0);
24
System.out.print(ucgenNesnesi.isimGetir() + ": ");
25
System.out.println(ucgenNesnesi.alanHesap());
26
// üçgen için alan hesapladık
27
}
28 }
29
Ekran çıktısı:
Daire Nesnesi:
1
7.024814731040727
2
Dikdörtgen Nesnesi: 15.0
3
Üçgen Nesnesi: 6.0
Yukarıdaki örneğimizde görüldüğü gibi geometrik şekil nesnelerimizi
tanımladık ve alan hesaplarını yaptık.alanHesap() metotlarını sınıflar
içerisinde override ettiğimiz için sonuç bütün sınıflar için özel hale geldi.
Şimdi soyut sınıflara bir örnek daha verelim. Bu örnekte de soyut sınıflarda
normal bir metot olabileceğini, soyut sınıftan nesne türetmeden doğrudan soyut
sınıf elemanlarına erişmeyi, static bir metot tanımlayarak, soyut sınıftaki
metoda erişmeyi anlatalım.
1
//soyutSinif.java - 09.04.2014
2
3
abstract class SoyutSinif
4
{
5
abstract public void goster(); // soyut metod
6
public SoyutSinif() // soyut sınıf yapıcısı
7
{
8
System.out.println("Burası Soyut Sınıf Yapıcısı");
9
}
10
public void metod() // normal metod
11
{
12
System.out.println("Soyut sınıfa ait normal metod");
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
}
public static void metod2() // static void
{
System.out.println("Soyut sınıfa ait static normal
metod");
}
}
class AltSinif1 extends SoyutSinif
{
public void goster() // soyut metod override edildi
{
System.out.println("Burası Alt Sınıf 1");
}
}
class AltSinif2 extends SoyutSinif
{
public void goster() // soyut metod override edildi
{
System.out.println("Burası Alt Sınıf 2");
}
}
public class Baslat
{
public static void main(String[] args)
{
AltSinif1 a1 = new AltSinif1();
AltSinif2 a2 = new AltSinif2();
a1.goster();
a2.goster();
SoyutSinif s1[] = new SoyutSinif[1];
s1[0] = a1;
s1[0].metod();
SoyutSinif.metod2();
}
}
Ekran çıktısı:
1
Burası Soyut Sınıf yapıcısı
2
Burası Soyut Sınıf yapıcısı
3
Burası Alt Sınıf 1
4
Burası Alt Sınıf 2
5
Soyut sınıfa ait normal metod
6
Soyut sınıfa ait static normal
metod
Bu örnekte yaptıklarımızı anlatalım.
1.
Soyut sınıfımızda bir normal metod, bir static metot
ve yapıcı tanımladık. Static olan metodu, sınıf adı ile doğrudan
erişebilmek amacıyla yaptık.
2.
Baslat adlı sınıfın main metodunda a1 ve a2 nesneleri oluşturduk. Bu
nesneler üzerinden goster()metotlarını çalıştırdık. Bu metotlar, soyut
olan metodu override etmektedirler.
3.
Bu nesneleri oluşturduğumuz anda otomatik olarak üst sınıfın
da yapıcısı çalıştığı için iki kere soyut sınıfımızın yapıcısı çalıştı.
4.
Soyut sınıftan nesne oluşturmayı dizi şeklinde yaptık ve a1 nesnesini
referans olarak verdik. Bu şekilde soyut sınıfımızın normal metoduna
ulaşabildik.
5.
Son olarak sadece sınıf adını kullanarak static olan metoda eriştik.
Istisnalar:
!
Farklı veriler alıp aynı işlemi yapacaksak, bunları soyut sınıflar
içerisinde yapmamız gerekir. Soyut sınıfların da kullanılma amacı
budur. İlk baştaki örneğimizde farklı parametreler aldık,
fakat aynı işi yaptık. Hepsinde alan bulma işlemi yaptık.
Ders 67 - Arayüz Kavramına Giriş
Arayüzler yapı olarak daha önceki dersimizde gördüğümüz soyut
sınıflara benzerler. Soyut sınıflara benzemelerine rağmen yapı olarak bazı
yönleriyle bu soyut sınıflardan ayrılır. Soyut sınıflarda, gövdesiz soyut
metodları ve tanımlayabileceğimiz diğer metodları kullanabiliyorduk.
Arayüzlerde ise bütün metodlar gövdesizolarak tanımlanır.
Arayüzler, sınıfların bir işi nasıl yapacağını değil, işi yaparken hangi adımları
veya ne yapması gerektiğini tanımlar. Arayüzler, temelde çoklu kalıtım olayını
basite indirgemek için oluşturulmuştur. Arayüzler, temelde çoklu kalıtım
olayını basite indirgemek için oluşturulmuştur. Arayüzlerin kod yapısı sınıf
tanımlamaya benzer. Sınıfları aşağıdaki gibi tanımlıyorduk.
erisimBelirteci class
1
sinifAdi
2
{
3
// metodlar ve
4
değişkenler
}
Bir arayüzü ise aşağıdaki gibi tanımlayabiliriz.
erisimBelirteci interface
1
arayuzAdi
2
{
3
// değişkenler ve metod
4
görevleri
}
Arayüzlerin çoklu kalıtım olayını basite indirgemek için oluşturulduklarını
söylemiştik. Arayüzlerin, sınıfları birleştirici özelliği vardır. Sınıflar, kullanmak
istediği arayüzü tanımından sonra impelements anahtar sözcüğü ile kendi
bünyelerine dahil edebilirler.
Arayüzlerde değişken erişim belirteçleri de sınıflardakinden farklıdır. Arayüz
içerisinde anlık değişkenler bulunmazlar. Arayüz içerisinde tanımladığımız
değişkenlerin erişim belirteçleri public static ve final tipindedir ve ilk değer
ataması zorunludur. Yani arayüzü kullanacak diğer sınıflar, değişkenleri
değiştiremezler. Arayüzler içerisinde tanımladığımız değişkenler, daha çok
diğer sınıflarda sabit olarak kullanacağımız değişkenlerdir.
Arayüzlerin yapı olarak soyut sınıflara benzediğini söylemiştik. Sınıflar sadece
bir adet soyut sınıfı miras alarak kullanabiliyorlardı. Arayüzlerde ise durum bu
açıdan farklıdır. Sınıflar, birden fazla arayüzü bünyesine katabilir. Bu da
çoklu kalıtımda bizim işimizi kolaylaştırır.
Istisnalar:
!
Arayüzler, soyut sınıflarda olduğu gibi hem gövdeli hem gövdesiz
metodlara sahip değildir. Tamamengövdesiz metodlar bulunur. Yani
bu metodlar başlı başına bir iş yapmazlar. Bu
metodların, implementedilen sınıflarda override edilmeleri gerekir.
Ders 68 - Arayüz Örneği
Şimdi bir örnek yaparak arayüzleri anlamaya çalışalım.
//calisan.java - 09.04.2014
1
2
public interface calisan // arayüz tanımlandı
3
{
4
double oran = 0.7;
5
double ucret();
6
void calisanBolumu();
7
void ucretBelirle(double ucretSabiti);
8
// bu arayüzü kullanacak olan sınıflarda tanımlayacağımız metodları
9
yazdık.
10
}
11
12
Yukarıda, diğer sınıflarımızda kullanacağımız arayüzümüzü tanımladık. Bu
arayüzün metodlarını, arayüzü kullanacağımız sınıflarda override ederek
yeniden tanımlamak zorundayız.
Şimdi sınıfımızı yazalım ve calisan arayüzlerden implement edelim.
isci.java
1
//isci.java - 09.04.2014
2
3
public class isci implements calisan
4
{
5
double ucretSabiti;
6
7
// çalışan ücretini döndüren metod
8
@Override
9
public double ucret()
10
{
11
return ucretSabiti * oran;
12
}
13
14
// çalışan bölümünü ekrana yazdıralım metod
15
@Override
16
public void calisanBolumu()
17
{
18
System.out.println("Ucretli Çalışan");
19
}
20
21
22
23
24
25
26
27
28
29
// çalışan ücretini belirtmek için kullanılacak
metod
@Override
public void ucretBelirle(double ucretSabiti)
{
this.ucretSabiti = ucretSabiti;
}
}
mudur.java
//mudur.java - 09.04.2014
1
2
public class mudur implements calisan
3
{
4
double ucretSabiti;
5
6
@Override
7
public double ucret()
8
{
9
return ucretSabiti;
10
}
11
12
@Override
13
public void calisanBolumu()
14
{
15
System.out.println("Yönetici");
16
}
17
18
@Override
19
public void ucretBelirle(double
20
ucretSabiti)
21
{
22
this.ucretSabiti = ucretSabiti;
23
}
24
}
25
26
satisElemani.java
1
//satisElemani.java - 09.04.2014
2
3
public class satisElemani implements calisan
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
double ucretSabiti;
double komisyon;
final double komisyonOran = 0.3;
@Override
public double ucret()
{
return ((ucretSabiti * oran) + komisyon);
}
@Override
public void calisanBolumu()
{
System.out.println("Satış Elemanı");
}
@Override
public void ucretBelirle(double ucretSabiti)
{
this.ucretSabiti = ucretSabiti;
}
// satış elemanının komisyonunu belirleyen
metod
public void satisKomisyonuBelirle(int adet)
{
komisyon = adet * komisyonOran;
}
}
Arayüzlerimizi kullanan sınıflarımızı yukarıda tanımladık. Görüldüğü gibi
arayüz içerisinde tanımladığımız metodlar, sınıflar içerisinde farklı şekillerde
kullanılmışlardır.
Şimdi ana sınıfımızı da yazarak örneğimizi tamamlayalım.
1
//arayuzOrnegi.java - 09.04.2014
2
3
public class arayuzOrnegi
4
{
5
public static void main(String[] args)
6
{
7
// işçi ile ilgili bilgiler yazdırılıyor.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
isci ucretliCalisan = new isci();
ucretliCalisan.calisanBolumu();
ucretliCalisan.ucretBelirle(865.70);
System.out.println("Maaşı: " +
ucretliCalisan.ucret());
// müdür ile ilgili bilgiler yazdırılıyor
mudur yonetici = new mudur();
yonetici.calisanBolumu();
yonetici.ucretBelirle(5519.71);
System.out.println("Maaşı: " + yonetici.ucret());
// satış elemanı ile ilgili bilgiler yazdırılıyor
satisElemani pazarlama = new satisElemani();
pazarlama.calisanBolumu();
pazarlama.ucretBelirle(978.75);
pazarlama.satisKomisyonuBelirle(250);
System.out.println("Komisyon: " +
pazarlama.komisyon);
System.out.println("Maaşı: " + pazarlama.ucret());
}
}
Ekran çıktısı:
Ucretli Çalışan
Maaşı: 605.99
1
Yönetici
2
Maaşı:
3
5519.71
4
Satış Elemanı
5
Komisyon:
6
75.0
7
Maaşı:
760.125
Örneğimizde tüm çalışanlar için kullanabileceğimiz metodların olduğu
bir arayüz oluşturduk. Daha sonrasında ise bu arayüzü kullanacağımız sınıflar
oluşturduk. Arayüzümüzde oluşturduğumuz metodları, bu
sınıflarda override ederek tekrar tanımladık. Ana sınıfımızda ise bu metodlara
değerlerimizi göndererekçalışan maaşlarını ve diğer bilgilerini ekrana
yazdırdık.
Istisnalar:
!
Arayüzler, soyut sınıflara benzese de aralarında önemli farklar vardır.
Eğer her metodun override (iptal) edilmesini istiyorsak, bu metodları
bir arayüz içerisinde tanımlarız. Ayrıca arayüzlerde, soyut sınıflarda
olduğu gibi bir ilişki kavramı yoktur. Yani arayüz ve bunu kullanan
sınıflar arasında kalıtım açısından bir bağlantı olmayabilir.
Ders 69 - Arayüzlerde Genişletilme Özelliği
Daha önceden tanımladığımız bir arayüzü genişletmemiz mümkündür. Bu bir
arayüzün başka bir arayüzü kalıtım yoluyla devralmasıyla mümkün olur. Bir
arayüzün diğer bir arayüzü miras alması, sınıftaki gibidir. Yani bir arayüz diğer
bir arayüzü extends anahtar sözcüğü ile miras alabilir.
Örnek olarak daha önceki konuda işlediğimiz satış elemanı sınıfını düşünelim.
Ücretli çalışanlarımız, komisyon yöntemiyle çalışmadığı için arayüzümüzde
komisyon ile ilgili herhangi bir metod tanımlamamıştık. Bu durumda eğer bu
arayüzümüze komisyon ile ilgili bir metot tanımlamak istersek, başka bir
arayüz tanımlayarak, bu işlemi gerçekleştirebiliriz.
Şimdi aşağıdaki örneği inceleyelim:
1
//calisan.java - 09.04.2014
2
3
public interface calisan // arayüz tanımlandı
4
{
5
double oran = 0.7;
6
double ucret();
7
void calisanBolumu();
8
void ucretBelirle(double ucretSabiti);
9
// bu arayüzü kullanacak olan sınıflarda tanımlayacağımız metodları
10
yazdık.
11
}
12
13
public interface calisanKomisyon extends calisan
14
{
15
// bu arayüzü, calışan arayüzünden miras aldık
16
double komisyonOran = 0.3;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public void satisKomisyonuBelirle(int adet);
// komisyon belirleyecek metodumuz
}
public class satisElemani implements calisanKomisyon
{
// bu sınıfı, calisanKomisyon arayüzünden implement ettik
double ucretSabiti;
double komisyon;
@Override
public double ucret()
{
return ((ucretSabiti * oran) + komisyon);
}
@Override
public void calisanBolumu()
{
System.out.println("Satış Elemanı");
}
@Override
public void ucretBelirle(double ucretSabiti)
{
this.ucretSabiti = ucretSabiti;
}
// satış elemanının komisyonunu belirleyen metod
@Override
public void satisKomisyonuBelirle(int adet)
{
komisyon = adet * komisyonOran;
}
}
Örnekte de görüldüğü gibi komisyonumuzu belirlemek için kullanacağımız
metodun gövdesini ve komisyonumuzu belirlemek için kullandığımız
oranımızı, ilk arayüzümüzü kalıtım yoluyla miras alan ikinci arayüzümüzde
yazdık. satisElemani sınıfımız da bu kez yeni oluşturduğumuz arayüzü
kullandı. Sınıfımız içerisinde ilk arayüzümüzün de
metodlarının override edilerek kullanıldığında dikkat edelim. Arayüzü
kullandığımız sınıfta, arayüzün kalıtım zincirindeki tüm
metodları override ederek kullanmak zorundayız.
Yani bir sınıf, bir arayüzden implement ediliyorsa ve bu arayüz de başka bir
arayüzden miras alınmışsa, sınıfımız bu iki arayüzdeki metodları
da override etmelidir.
Son bir örnek vererek konumuzu kapatalım.
1
//Canli.java - 09.04.2014
2
3
interface Canli
4
{
5
public void nefesAl();
6
}
7
8
interface Hayvan extends Canli
9
{
10
public void avlan();
11 }
12
13 interface Surungen extends Hayvan
14 {
15
public void surun();
16 }
17 // yukarıda 3 adet arayüz tanımlandı
18
19 // tavşan sınıfı
20 class Tavsan implements Hayvan
21 {
22
public void nefesAl()
23
{
24
System.out.println("Nefes
25 alıyor");
26
}
27
public void avlan()
28
{
29
System.out.println("Avlanıyor");
30
}
31 }
32
33 // timsah sınıfı
34 class Timsah implements Surungen
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
public void avlan()
{
System.out.println("Avlanıyor");
}
public void surun()
{
System.out.println("Sürünüyor");
}
public void nefesAl()
{
System.out.println("Nefes
Alıyor");
}
}
Bu örneğimizde 3 adet arayüz tanımladık. Bu
arayüzlerden Hayvan arayüzünden Tavsan sınıfınıimplement ettik. Surungen
arayüzünden
de Timsah sınıfını implement ettik. Tavsan sınıfımız, Hayvan veCanli arayüz
lerindeki metodları override etmek zorunda kaldı. Çünkü Hayvan arayüzü
de Canli arayüzünden türetilmiştir(miras).
Timsah sınıfımız ise, hem Hayvan hem Canli hem
de Surungen arayüzlerindeki metodları override etmek zorunda kaldı. Bunun
sebebi de Surungen arayüzünün Hayvan arayüzünden, Hayvan arayüzünün
ise Canliarayüzünden miras alınmasıdır.
Istisnalar:
!
Bir arayüz içerisinde aynı isimde 2 metod varsa, bu metodların aldığı
parametrelerin farklı olması gerekir.Dönüş tiplerinin farklı olması
bir anlam ifade etmez, hata oluşur. Bu,
metodlardaki overload işlemine benzer.
Ders 70 - Arayüz İçerisinde Başka Bir Arayüz Kulanma
Bir arayüz, başka bir arayüz içerisinde bulunabilir. Yukarıda anlattığımız gibi
bu dahili arayüzler de publicolarak tanımlanmalıdır.
Örnek vererek açıklayalım ve kullanımını görelim.
1
//Calistir.java - 09.04.2014
2
3
interface Arayuz1
4
{
5
interface Arayuz2 // arayüz içinde arayüz
6
{
7
public void metod2();
8
}
9
public void metod1();
10
}
11
12
interface Arayuz3
13
{
14
public void metod3();
15
}
16
17
class Sinif1 implements Arayuz1
18
{
19
public void metod1() // Arayuz1'deki metod1 override
20
edildi
21
{
22
System.out.println("Arayüz1'deki metod1 override
23
edildi");
24
}
25
}
26
27
class Sinif2 implements Arayuz1.Arayuz2
28
{
29
public void metod2() // Arayuz2'deki metod2 override
30
edildi
31
{
32
System.out.println("Arayüz2'deki metod2 override
33
edildi");
34
}
35
}
36
37
class Sinif3 implements Arayuz3
38
{
39
public void metod3() // Arayuz3'deki metod3 override
40
edildi
41
{
42
43
44
45
46
47
48
49
50
51
52
53
54
System.out.println("Arayüz3'deki metod3 override
edildi");
}
}
public class Calistir
{
public static void main(String[] args)
{
Sinif1 s1 = new Sinif1();
s1.metod1();
Sinif2 s2 = new Sinif2();
s2.metod2();
Sinif3 s3 = new Sinif3();
s3.metod3();
}
}
Ekran çıktısı:
Arayüz1'deki metod1 override
edildi
1
Arayüz2'deki metod2 override
2
edildi
3
Arayüz3'deki metod3 override
edildi
Örneğimizde Arayuz1 içerisinde Arayuz2 adında başka bir arayüz tanımladık.
Bu Arayuz2 içerisine demetod2 adında bir metot
tanımladık. Arayuz1 içerisinde de metod1 adında bir metod bulunmaktadır. Bu
arayüzlere erişim belirleyici tanımlamadık, çünkü varsayılan
olarak public tanımlanmıştır.
Arayuz3 içerisine de metod3 adında bir metot tanımladık. Daha
sonra main metodunda bu arayüzleri kullanan sınıfları çağırdık. Bu 3 sınıfta da
(Sinif1, Sinif2, Sinif3) implement edildikleri arayüzlerde bulunan metodları
override ettik.
Ders 71 - Dahili Sınıflara Giriş
Java dilinde diğer dillerdeki çoklu kalıtım yoktur. Java çoklu
kalıtımı arayüz (interface) ve dahili sınıflar(inner classes) ile sağlar. Dahili
sınıfları, sınıf içerisinde tanımlanmış sınıflar olarak belirtebiliriz. Dahili sınıflar
bir bütünü oluşturan parçaları bütün olarak tanımlamamıza imkan sunar. Dahili
sınıflar, Java'ya 1.1 sürümüyle beraber dahil olmuştur. Dahili sınıfları 3 ana
grupta inceleyebiliriz. Bunlar:

Dahili Üye Sınıflar (static üye sınıflar, static olmayan üye sınıflar)

Yerel Sınıflar

İsimsiz Sınıflar
Ders 72 - Dahili Üye Sınıflar
Dahili üye sınıflar, sınıf içerisinde tanımlanmış sınıflardır. Dahili üye sınıflar
sayesinde parçalar bir araya gelerek bütünü oluşturabilirler. Örnek olarak bir
bilgisayarı ele alalım. Bilgisayar parçalardan oluşmaktadır. Her parçanın bir
sınıf olarak tanımlandığı bir sınıf oluşturalım.
1
//bilgisayar.java - 09.04.2014
2
3
public class bilgisayar
4
{
5
public class anakart
6
{
7
// 1. dahili üye sınıf
8
// kodlar
9
}
10
11
public class islemci
12
{
13
// 2. dahili üye sınıf
14
// kodlar
15
}
16
17
public class RAM_Bellek
18
{
19
// 3. dahili üye sınıf
20
// kodlar
21
}
22
}
23
24
25
26
27
28
29
public static void main(String args[])
{
bilgisayar.RAM_Bellek = new bilgisayar().new
RAM_Bellek();
}
Örnekte görüldüğü gibi bilgisayar parçaları, bilgisayar sınıfı altında
tanımlanarak bilgisayar sınıfını oluşturdu. Burada bilgisayar parçaları, dahili
üye sınıfları oluşturmaktadır. Örnekte dikkat etmemiz gereken bir diğer nokta
ise, RAM_Bellek sınıfının nesnesidir. Bu sınıfın direk olarak
nesnesini oluşturamayız. Dahili sınıfın nesnesini oluşturabilmek için örnekte
de olduğu gibi üst sınıf üzerinden nesnemizi oluşturabiliriz.
Basit bir başka örnek verelim.
//islemYap.java - 09.04.2014
1
2
public class islemYap
3
{
4
public class DahiliUyeSinif
5
{
6
public void metod1()
7
{
8
System.out.println("Dahili üye sınıfın metodu");
9
}
10
public void metod2(int a, int b)
11
{
12
System.out.println(a * b);
13
}
14
}
15
public static void main(String args[])
16
{
17
islemYap.DahiliUyeSinif n1 = new islemYap().new
18
DahiliUyeSinif();
19
n1.metod1();
20
n1.metod2(4, 8);
21
}
22
}
23
24
Ekran çıktısı:
Dahili üye sınıfın
1
metodu
2
32
Örneğimizde dahili üye sınıf oluşturduk ve içerisinde iki metot tanımladık.
Daha sonra main metodu içerisinde de bu dahili sınıftan bir nesne oluşturarak,
bu nesne üzerinden metotları çağırdık.
Ders 73 - Dahili Üye Sınıflar ve Erişim Belirteçleri
Dahili üye sınıfları normal sınıflar gibi erişim belirteçleriyle nitelendirebiliriz.
Böylece dahili sınıfımızı diğer dahili sınıflarımıza karşı kısıtlamış oluruz. Fakat
dikkat edilmesi gereken bir diğer önemli nokta ise; üst sınıf ve dahili sınıf
ilişkisidir. Erişim belirteci ne olursa olsun üst sınıf metotları, dahili sınıfın
elemanlarına ve metotlarınaerişebilirler. Daha önceki dersimizdeki örneği ele
alırsak, örneğimizde bilgisayar sınıfı oluşturmuştuk ve içerisinde birimleri
dahili sınıf şeklinde oluşturmuştuk. Örneğimizde erişim
belirteçlerimiz public'ti. Herhangi bir sınıf private tanımlansaydı, bu sınıfa
erişim sadece üst sınıfın metotları sayesinde olur. Diğer dahili sınıfların
metotları için dahili sınıfın içeriği kısıtlanmış olur.
1 //dahiliSinifOrnegi.java - 09.04.2014
2
3 import java.util.ArrayList;
4
5 public class dahiliSinifOrnegi
6 {
7
//1. dahili sınıf asal sayı hesaplama için kullanılır
8
public class asalSayi
9
{
10
public boolean asalSayi(int asalSayi)
11
{
12
int bolen = 0;
13
boolean kontrol;
14
15
for(int i = 2 ; i < asalSayi ; i++)
16
{
17
if(asalSayi % i == 0)
18
bolen++;
19
}
20
21
if(bolen == 0)
22
kontrol = true;
23
else
24
kontrol = false;
25
26
return kontrol;
27
}
28
}
29
30
//2. dahili sınıf mükemmel sayı hesaplama için kullanılır.
31
protected class mukemmelSayi
32
{
33
// kendisi hariç bölenleri toplamı kendisine eşit olan sayı mükemmel
34 sayıdır
35
protected boolean mukemmelSayi(int mukemmelSayi)
36
{
37
int bolenToplam = 0;
38
boolean kontrol;
39
40
for(int i = 1 ; i < mukemmelSayi ; i++)
41
{
42
if(mukemmelSayi % i == 0)
43
bolenToplam += i;
44
}
45
46
if(bolenToplam == mukemmelSayi)
47
kontrol = true;
48
else
49
kontrol = false;
50
51
return kontrol;
52
}
53
}
54
55
//3. dahili sınıf fibonacci elemanlarını bulmak için kullanılır
56
private class fibonacciSerisi
57
{
58
// fibonacci dizisi, her sayının kendinden öncekiyle toplanması
59
// sonucu oluşan sayı dizisidir. ilk 2 elemanı 1'dir.
60
private ArrayList fibonacciSerisi(int elemanSayisi)
61
{
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
ArrayList<Integer> fibonacci = new ArrayList<Integer>();
fibonacci.add(0, 1);
fibonacci.add(1, 1);
// ilk iki indise 1'i ekledik
for(int i = 0 ; i < elemanSayisi-2 ; i++)
{
fibonacci.add(i+2, fibonacci.get(i) + fibonacci.get(i+1));
// bir sonraki indise ardışık indise sahip dizilerin elemanları
toplanarak ekleniyor
}
return fibonacci;
}
}
public static void main(String[] args)
{
// dahili sınıflarımız için birer nesne oluşturduk
dahiliSinifOrnegi.asalSayi asal = new dahiliSinifOrnegi().new
asalSayi();
dahiliSinifOrnegi.mukemmelSayi mukemmel = new
dahiliSinifOrnegi().new mukemmelSayi();
dahiliSinifOrnegi.fibonacciSerisi fibonacci = new
dahiliSinifOrnegi().new fibonacciSerisi();
System.out.println(asal.asalSayi(5));
System.out.println(asal.asalSayi(413));
System.out.println(mukemmel.mukemmelSayi(6));
System.out.println(mukemmel.mukemmelSayi(12));
System.out.println(fibonacci.fibonacciSerisi(7));
System.out.println(fibonacci.fibonacciSerisi(11));
}
}
Ekran çıktısı:
true
1
false
2
true
3
false
4
[1, 1, 2, 3, 5, 8, 13]
5
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55,
6
89]
Yukarıdaki örneğimizde üç adet dahili sınıf bulunmaktadır. Bunlardan ilkinin
erişim belirteci public, ikincisinin protected ve üçüncüsünün
ise private'dir. main metodu ise ana sınıfımızın bir üyesidir. Örneğimizde ilk
olarak verilen sayının asal sayı olup olmadığını kontrol eden asalSayi sınıfını
ve bu sınıfın yapılandırıcısını yazdık. İkinci olarak yine verilen sayının, bu
sefer mükemmel sayı olup olmadığını kontrol eden sınıfı ve yapılandırıcısını
yazdık. Üçüncü olarak ise; istenilen sayıda elemanı olan fibonacci
serisiniüretecek sınıfı ve bu sınıfın yapılandırıcısını yazdık. Bundan sonraki
kısımda ana sınıfımızın bir üyesi olanmain() metodu içerisinde bu dahili
sınıfların nesnelerini oluşturduk. Burada private erişim
belirteçlifibonacciSerisi sınıfını tanımlarken, hata almadığımıza dikkat
edelim. main metodumuz başka bir sınıfın üyesi olsaydı bu tanımlamayı
yaparken hata alacaktık. Daha sonrasında ise metotlarımıza değer vererek,
dönen sonuçları ekrana yazdırdık.
Ana sınıfın, dahili üye sınıfın tüm alanlarına erişebileceğinden bahsettik. Aynı
şekilde dahili üye sınıf,kendisini çevreleyen sınıfın tüm alanlarına erişebilir.
Istisnalar:
!
Eğer dahili üye sınıfımızı static olarak tanımlarsak, bu dahili sınıfın
elemanlarına erişmek içinanasınıf.dahilisınıf ile değil de doğrudan
o sınıfın adı ile nesne oluştururuz.
Yukarıda anlattığımız nota bir örnek verelim.
1
//islemYap.java - 09.04.2014
2
3
public class islemYap
4
{
5
// normal dahili üye sınıf ve normal sınıf üyeleri
6
public class DahiliUyeSinif
7
{
8
private int x;
9
private int y;
10
public DahiliUyeSinif(int sayi1, int sayi2)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
x = sayi1;
y = sayi2;
}
public void carp()
{
System.out.println("Çarpma sonucu: " + (x * y));
}
}
// static dahili üye sınıf ve static üyeler
public static class DahiliUyeSinif2
{
public static void topla(int sayi1, int sayi2)
{
System.out.println("Toplama sonucu: " + (sayi1 + sayi2));
}
}
// islemYap sınıfına ait main metodu
public static void main(String[] args)
{
islemYap.DahiliUyeSinif a = new islemYap().new
DahiliUyeSinif(5, 8);
a.carp();
DahiliUyeSinif2.topla(5, 2); // nesnesiz erişme
}
}
Ekran çıktısı:
Çarpma sonucu:
1
40
2
Toplama sonucu:
7
1.
Örneğimizde 2 dahili sınıf oluşturduk. İlk dahili sınıfımızda
bir yapıcı bulunuyor ve aldığı parametreleri x ve y değişkenlerine
atıyor. Buradan anlıyoruz ki dahili sınıflarda yapıcı olabilir. Fakat bu
dahili sınıflardan bir nesne oluşturulduğu zaman, yapıcısı otomatik
olarak çağırılmaz.
2.
main metodunda bu sınıfın carp() metodunu çağırmak
için anasınıf.dahilisınıf yapısı ile nesne oluşturarak eriştik.
3.
Diğer dahili sınıfımızı ise static tanımladık ve
içerisindeki topla() metodunu da static tanımladık. Bu metot ise,
aldığı değerleri topluyor ve ekrana gösteriyor. Bu
metoda main içerisinden erişmek için ise herhangi bir nesne
oluşturmamıza gerek kalmadı. Çünkü hem sınıfımızın static hem de
içerisindeki metodumuz static'tir.
Şimdi de static olan ve olmayan dahili sınıflar tanımlayalım ve bu sınıfların
içerisinde hangi tipte elemanlar olabilir, ona bakalım.
1
//islemYap2.java - 09.04.2014
2
3
public class islemYap2
4
{
5
class DahiliUyeSinif
6
{
7
public int x = 5;
8
public static final int y = 5;
9
public static String ad = "Okan"; //
10
tanımlanamaz
11
public static void metod1()
//
12
tanımlanamaz
13
{
14
// metod gövdesi
15
}
16
}
17
static class DahiliUyeSinif2
18
{
19
public int a = 11;
20
public static final int b = 23;
21
public static String ad = "Onur";
22
public static void metod2()
23
{
24
// metod gövdesi
25
}
26
public void metod3()
27
{
28
// metod gövdesi
29
}
30
31
}
}
Örneğimizde static olan ve olmayan 2 dahili sınıf tanımladık. Static
olmayan sınıfımızın içerisinde static bir değişken ve metot tanımlayamadık.
Fakat hem static hem de final olan değişkenleri kullanabildik. Bunlar da
bildiğiniz üzere sabitler'dir.
Istisnalar:
!
Static dahili sınıflar içerisinde ise static olan ve olmayan her türlü
metot ve değişkenler tanımlanabilir. Ayrıca static olan
sınıflar, static metotlar gibi içinde bulunduğu sınıfın static
olmayan elemanlarınaerişemez. Fakat static olan alanlara erişebilir.
Istisnalar:
!
Static olmayan üye sınıflar ise, içinde bulunduğu sınıfın static
olan ve olmayan alanlarına erişebilir. Bunlarıstatic metodlar gibi
düşünebiliriz.
Bu başlık altında anlatacağımız son özellik şudur: Bir sınıf içerisinde dahili
sınıf tanımlayabiliyorduk. Bu dahili sınıf içerisinde de yine bir dahili
sınıf tanımlayabiliriz. Örnek vererek açıklayalım.
1
//AnaSinif.java - 09.04.2014
2
3
import AnaSinif.DahiliUyeSinif1.DahiliUyeSinif2;
4
5
public class AnaSinif
6
{
7
static class DahiliUyeSinif1
8
{
9
static class DahiliUyeSinif2
10
{
11
static void yazdir()
12
{
13
System.out.println("En içteki dahili sınıfın
14
metodu");
15
}
16
}
17
18
19
20
21
22
23
}
public static void main(String[] args)
{
DahiliUyeSinif2.yazdir();
}
}
Ekran çıktısı:
En içteki dahili sınıfın
1
metodu
Yukarıdaki örnekte iç içe dahili sınıflar tanımladık. main metodumuzun
içerisinde de doğrudan sınıf adınıkullanarak metodumuzu çağırdık. Çünkü
örneğimizde dahili sınıfları static olarak tanımladık.
Ders 74 - Yerel Sınıflar
Yerel sınıflar, metot içerisinde tanımlanan sınıflardır. Dahili üye sınıfların,
kendilerini çevreleyen sınıfları olduğunu anlatmıştık. Yerel sınıfların ise
kendilerini çevreleyen metotlar vardır. Yerel sınıfların en önemli
özelliği, sadece bu metot içerisinden erişilebilir olmasıdır. Yani metot
dışarısından yerel sınıflara erişip bu sınıfları kullanamayız. Yerel sınıflar metot
dışarısında tanımlanan arayüzlere erişebilirler. Yerel sınıflar, içeirisinde
bulundukları metotların sadece final olarak işaretlenmiş değişkenlerine
ulaşabilirler. Yerel sınıfların bir diğer özelliği de erişim belirtecine sahip
olamazlar. Yani bir yerel
sınıfı public, protected veya privatetanımlayamayız. Yerel sınıfları
sadece friendly erişim belirteciyle işaretleyebiliriz.
Yerel sınıfları daha iyi anlayabilmek için bir örnek yapalım.
1
//yerelSinifOrnegi.java - 09.04.2014
2
3
interface fonksiyonlar // interface tanımlandı
4
{
5
public double faktoriyelAl(double sayi);
6
}
7
public class yerelSinifOrnegi
8
{
9
public double faktoriyel(double sayi)
10
{
11
// yerel sınıfı çevreleyen metod
12
double sonuc;
13
class faktoriyelAlma implements fonksiyonlar
14
{
15
// yerel sınıf
16
private double sonuc2 = 1;
17
@Override
18
public double faktoriyelAl(double sayi2)
19
{
20
for(int i = 1 ; i <= sayi2 ; i++)
21
{
22
sonuc2 *= i;
23
}
24
return sonuc2;
25
}
26
}
// yerel sınıfın bir nesnesini oluşturduk
faktoriyelAlma f = new faktoriyelAlma();
sonuc = f.faktoriyelAl(sayi);
return sonuc;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
}
public void hesaplama()
{
// faktoriyelAlma f = new faktoriyelAlma(); yaparsak
// metodumuz, sınıfı tanımadığından hata ile
karşılacaksınız
}
public static void main(String args[])
{
yerelSinifOrnegi y = new yerelSinifOrnegi();
System.out.println("9'un faktoriyeli: " +
y.faktoriyel(9));
}
}
Ekran çıktısı:
9'un faktoriyeli:
1
362880.0
Örneğimizde sınıfımız içerisinde bir metod oluşturduk ve bu metodumuzun
içerisinde bir yerel sınıfoluşturduk. İşlemlerimizi yerel sınıf içerisinde yaptık.
Dönen sonuca dikkat ettiğimizde, main metoduna
gönderdiğimiz sonuc değişkeni ile asıl sonuc değişkeni farklıdır. Bunun
sebebi main metodu içerisinden direk olarak yerel sınıf metotlarına veya
değişkenlerine ulaşamadığımızdandır. Örnekte görüldüğü gibi metodumuz
dışarısında boş bir metot tanımladık ve bu metottan yerel sınıfımıza erişmeye
çalıştık. Böyle bir durumda metodumuz yerel sınıfı görmediğinden hata ile
karşılaşacağız. Son olarak tanımladığımız ana metottan dönen sonucu ekrana
yazdırdık ve örneği sonlandırdık.
!
Istisnalar:
Yerel sınıflar da dahili sınıflar gibi yapıcıya sahip olabilirler.
Ders 75 - İsimsiz Sınıflar
İsimsiz sınıflar, isim kullanılmadan tanımlanabilen sınıflardır. İsimsiz sınıflar,
başka sınıflardan türetilemez ve bir arayüzü implement edemezler. Ayrıca
isme sahip olmadıkları için yapılandırıcı metotlarıda yoktur.
Bu konuyla ilgili kısa bir örnek yaparak konuyu sonlandıralım.
//isimsizSinifOrnegi.java - 09.04.2014
1
2 interface Faktoriyel // interface tanımlandı
3 {
4
public double hesap();
5 }
6
7 public class isimsizSinifOrnegi
8 {
9
public Faktoriyel faktoriyelAl(final double sayi)
10
{
11
return new Faktoriyel()
12
{
13
// arayüz içerisindeki metodları kullanmak için isimsiz bir sınıf
14 oluşturduk
15
@Override
16
public double hesap()
17
{
18
double x = 1;
19
for(int i = 1 ; i <= sayi ; i++)
20
x *= i;
21
return x;
22
}
23
}; // noktalı virgül kullanıldı
24
}
25
public static void main(String[] args)
26
{
27
isimsizSinifOrnegi i = new isimsizSinifOrnegi();
28
// metodumuz faktöriyel tipinde değer döndürdüğü için bu tipte nesne
29 tanımlıyoruz
30
Faktoriyel f = i.faktoriyelAl(7);
31
System.out.println("7'nin faktoriyeli: " + f.hesap());
32
}
33 }
34
Ekran çıktısı:
7'nin faktoriyeli:
1
5040.0
Örneğimizde yine sınıf içerisinde daha önceki örneğimizde olduğu gibi
bir faktöriyel alma metodu tanımladık. Metodumuzu dönüş
tipini, arayüzümüz olarak verdik ve bu sayede return kelimesinden sonra,
arayüzün metodunu isimsiz bir sınıf içerisinde tanımlamadık. Faktöriyel alma
metodumuzun parametresine baktığımızda, final kelimesiyle işaretlendiğini
görüyoruz. Bunun sebebi ise; isimsiz sınıfların içerisinde kullanıldıkları
metotların veya sınıfların, sadece final tipteki değişkenlerine erişebiliyor
olmasındandır. İsimsiz sınıfımızdan sonra noktalı virgül kullandığımıza da
dikkat edelim. Bunun sebebi ise return kelimesinden sonra tanımladığımız
isimsiz metodumuzun, bir değer olarak algılanmasıdır.
Istisnalar:
!
Dahili sınıflar, nesneye yönelik programlamanın temel taşlarından biri
olan Kapsülleme'ye destek verdiği için bir üstünlük sağlar. İç içe
sınıfları yazarak, sınıflar arasındaki ilişkiyi düzenler ve bu sınıfları
kolayca yönetmemizi sağlar.
Ders 76 - Çok Biçimlilik (Polimorfizm) Kavramına Giriş
Polimorfizm; yani Çok Biçimlilik, Kalıtım kavramı ile iç içedir. Birbirleriyle
beslenirler. Kalıtım konusunda sınıfları türetmeyi görmüştük. Türetilen sınıflar,
türediği üst sınıfın öğelerine sahip oluyorken bunun tersi geçerli değildi. Yani
temel sınıflar, alt sınıfların üyelerine sahip olamazlar. Polimorfizm yapabilmek
için Kalıtımmantığını bilmek gerekir.
Polimorfizm, çoklu biçim veya çoklu şekil anlamına gelir. Yani Polimorfizm
yapılarak bir nesne, farklı nesneler gibi davranabilir. Bir nesne, farklı
sınıflardan oluşturulmuş nesneleri yüklenebilir.
Örnek üzerinde Polimorfizm konusunu anlatalım.
1
//Polimorfizm.java - 09.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class UstSinif
{
public void yaz()
{
System.out.println("Burası üst sınıf");
}
}
class AltSinif1 extends UstSinif // miras alındı
{
public void yaz() // override edildi
{
System.out.println("Burası alt sınıf1");
}
}
class AltSinif2 extends UstSinif // miras alındı
{
public void yaz() // override edildi
{
System.out.println("Burası alt sınıf2");
}
}
public class Polimorfizm
{
public static void nesneAl(UstSinif nesne)
{
nesne.yaz();
}
public static void main(String[] args)
{
UstSinif u1 = new UstSinif();
AltSinif1 a1 = new AltSinif1();
AltSinif2 a2 = new AltSinif2();
nesneAl(u1); // nesneAl metoduna parametre olarak
gönderildi
nesneAl(a1); // nesneAl metoduna parametre olarak
gönderildi
nesneAl(a2); // nesneAl metoduna parametre olarak
gönderildi
}
}
Ekran çıktısı:
1
2
3
Burası üst sınıf
Burası alt
sınıf1
Burası alt
sınıf2
Örneğimizde 3 sınıfımız var. En tepede UstSinif, bunlardan türemiş
olan AltSinif1 ve AltSinif2 sınıfları vardır. Bu türetilmiş
sınıflar, super sınıftaki yaz() metodunu override yani iptal etmişlerdir.
main() metodumuzda bu 3 sınıftan 3 nesne oluşturduk ve daha sonra bu
nesneleri nesneAl() metoduna parametre olarak gönderdik, dikkat edelim.
Bu nesneAl() metodu, parametre olarak UstSinif tipinde nesne adında
bir parametre alıyor. Bu nesneparametresi, hem u1 hem a1 hem
de a2 nesnelerinin yerine geçti. Yani bu 3 sınıf tipinde de nesneler aldı.
Yani birçok biçime girdi. İşte Polimorfizm kavramının temelinde de bu yatar.
Biz bu metoda 3 defa parametre gönderdik. Bu parametre olan nesnelerin her
biri farklı sınıflardan türetilmişlerdir. nesneAl() metodunda ise, bu
alınan nesne üzerinden yaz() metodu çağırılır. Peki, AltSinif1'den türetilen
nesne, bu metoda gönderildiğinde, metodun parametresi UstSinif tipindendir.
Acaba hangi sınıfa ait yaz() metodu çalışıyor?
AltSinif1 sınıfı, UstSinif'daki metodu override ettiği
için AltSinif1'deki yaz() metodu çağırılmıştır.
Başka bir örnek verelim ve konumuzu daha iyi anlayalım.
1
//Polimorfizm.java - 09.04.2014
2
3
class Canli
4
{
5
public void yaz()
6
{
7
System.out.println("Canli Sınıfı");
8
}
9
}
10
11
class Insan extends Canli
12
{
13
public void yaz()
14
{
15
System.out.println("Insan Sınıfı");
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
}
}
class Hayvan extends Canli
{
public void yaz()
{
System.out.println("Hayvan
Sınıfı");
}
}
class Bitki extends Canli
{
public void yaz()
{
System.out.println("Bitki Sınıfı");
}
}
public class Polimorfizm2
{
public static void nesneAl(Canli c)
{
c.yaz();
}
public static void main(String[] args)
{
Canli c = new Canli();
Insan i = new Insan();
Hayvan h = new Hayvan();
Bitki b = new Bitki();
nesneAl(c);
nesneAl(i); // upcasting(yukarı
çevrim)
nesneAl(h); // upcasting
nesneAl(b); // upcasting
}
}
Ekran çıktısı:
1
Canli Sınıfı
2
Insan Sınıfı
3
4
Hayvan
Sınıfı
Bitki Sınıfı
Bu örneğimizde nesneAl() metodu Canli tipinde bir parametre alıyor. Fakat
bu Canli tipindeki parametreye biz Insan, Hayvan, Bitki tipinde de
parametreler gönderdik. Buna kızmaz. Çünkü yukarı çevrimyaptık. Yani
bizim gönderdiğimiz nesnenin olduğu sınıf, zaten Canli sınıfından türemiştir.
Yani her bitki bir canlıdır veya her hayvan bir canlıdır. Yani
metodumuz Canli tipinden parametre alıyor ama alınan parametrenin olduğu
sınıf da (Hayvan) zaten Canli sınıfının bir alt sınıfıdır. Kalıtım ile ilişkisi de
burada başlıyor. Alt sınıflardan oluşturulan nesneler, üst sınıfın referansına
bağlanabiliyor.
Burada Canli sınıfından yani Canli tipinden parametre alıyor fakat
buna Hayvan tipinde bir parametre gönderiliyor. Peki
bu c nesnemiz Canli tipinde midir, yoksa Hayvan tipinde
mi? Polimorfizm dediğimiz gibi burada karşımıza çıkıyor. c nesnemiz
üzerinden yaz() metodu çağırılınca Hayvan mı, yoksa Canli sınıfının
mıyaz() metodu çağırılacak? Cevap Hayvan sınıfına ait yaz() metodu.
Hayvan sınıfımız, Canli sınıfından türediği için
öncelik Hayvan sınıfının yaz() metodudur.
Eğer Hayvan sınıfında override yapmasaydık veya Hayvan sınıfımızın
içi boş olsaydı ne olacaktı? O zaman çıktıdaki 3. satırda yine Canli
sınıfı yazacaktı. Çünkü kendine yaz() metodu olmayınca üst
sınıftakiyaz() metodunu çağıracaktı.
Bu örnekte c nesnemiz, yani c parametremiz aslında yaptığı iş şudur:
Canli c = new Canli();
1
Canli c = new Insan();
2
Canli c = new
3
Hayvan();
4
Canli c = new Bitki();
Yani parametre olan c değerimizin 4 sınıfa ait referansları vardır. Peki, biz
bu parametrenin tipini Canlideğil de Hayvan yapsaydık ne olacaktı? O zaman
da sadece Hayvan tipindeki nesneyi parametre olarak alacaktı.
Çünkü Hayvan sınıfından türemiş başka bir sınıf yoktur. Ama tüm
sınıflar Canli sınıfından türemişlerdir. Yani kendi sınıfı ve alt sınıflarından
oluşturulan nesneleri alabilecekti.
Biz bu bilgileri verdikten sonra Polimorfizm ile ilgili az çok bir şeyler oluştu
kafamızda. Polimorfizmde, bir nesnemiz birden fazla nesneye bağlanabilir.
Istisnalar:
!
Polimorfizm yaptığımızda hangi nesnenin metodunun
çağırılacağı, çalışma anında belirlenir. Çünkü program çalıştığında
nesneyi kullanacak olan metoda parametre göndeririz. Derleme
anında bu metodun hangi nesneyi kullanacağı belli değildir.
Eğer yukardaki son
örneğimizde Polimorfizm kullanmasaydık nesneAl() metodumuzu aşağıdaki
gibi uzun uzun yazmak zorunda kalacaktık. Polimorfizm bizi bundan
kurtarıyor. Burada gelen parametremizin hangi sınıfa ait olduğu kontrol edilip
ona göre yaz() metodu çağırılıyor. Polimorfizm ile nesnemiz üzerinde
karşılaştırma yapmadan nesnenin referansına göre işlem yaptırabiliyoruz.
1
//09.04.2014
2
3
public static void nesneAl(Canli c)
4
{
5
if(c instanceof Canli) // c, canli sınıfından
6
oluşturulmuşsa
7
{
8
Canli c1 = c;
9
c1.yaz();
10
}
11
else if(c instanceof Insan)
12
{
13
Insan c1 = (Insan)c; // c nesnesi insan sınıfına cast
14
edildi
15
c1.yaz();
16
}
17
else if(c instanceof Hayvan)
18
{
19
Hayvan c1 = (Hayvan)c;
20
c1.yaz();
21
}
22
23
24
25
26
27
else if (c instanceof Bitki)
{
Bitki c1 = (Bitki)c;
c1.yaz();
}
}
Polimorfizm, bizi bu kodları yazmaktan kurtarır. Buradaki instanceof anahtar
kelimesini de bir sonraki konuda anlatacağız. Bu anahtar kelimenin görevi,
nesnelerin ait olduğu yani oluşturulduğu sınıfı kontrol eder. Eğer o sınıftan
oluşturulmuş ise true değilse false döner.
Cast işleminin sebebi de şudur: Parametremiz Canli tipindedir. Fakat bu
parametreyi, örneğin Insansınıfındaki bir nesneye aktarmak
istediğimizde, cast işlemi yapmak zorundayız. Çünkü atanan nesnelerin
sınıfları farklıdır.
Ders 77 - Geç Bağlama
Bir önceki dersimizde metodlarımıza parametre olarak nesne gönderdik ve bu
çağırılan metodların hangi nesne üzerinden çalıştırılacağını Java belirledi.
Buna Geç Bağlama diyoruz. Yani bu bağlama işlemi çalışma zamanında belli
olmuştu. Fakat eğer çalışma zamanında değil de derleme zamanında belli
olmuş olsaydı, buna da Erken Bağlama diyecektik. Biz bu dersimizde Geç
Bağlama'yı ele alacağız.
Geç Bağlama'yı anlatmak için Erken Bağlama'dan olan farkını bir örnekle
anlatmamız gerekiyor. Örnek olarak rastgele sayıları verelim. Rastgele sayı
üreten bir programımız olsun. Bu rastgele sayılar derleme
anında oluşturulmaz. Programımızı çalıştırdığımızda ancak bu rastgele olan
sayılar üretilmeye başlar. Geç Bağlama'da da mantık bu şekildedir.
Eğer rastgele olarak bir nesne üretir ve bu nesneleri de metodagönderirsek,
çağırılan metodun hangi nesne üzerinden çağırılacağı çalışma anında belli
olur.
Buna bir örnek verelim ve Geç Bağlama'yı örnek üzerinde gösterelim.
1
//Polimorfizm.java - 09.04.2014
2
3
class Canli
4
{
5
public void yaz()
6
{
7
System.out.println("Canli Sınıfı");
8
}
9
}
10
class Insan extends Canli
11
{
12
public void yaz()
13
{
14
System.out.println("Insan Sınıfı");
15
}
16
}
17
class Hayvan extends Canli
18
{
19
public void yaz()
20
{
21
System.out.println("Hayvan Sınıfı");
22
}
23
}
24
class Bitki extends Canli
25
{
26
public void yaz()
27
{
28
System.out.println("Bitki Sınıfı");
29
}
30
}
31
public class Polimorfizm
32
{
33
public static void nesneAl(Canli c)
34
{
35
c.yaz();
36
}
37
public static void main(String[] args)
38
{
39
Canli[] h = new Canli[3];
40
for(int i = 0 ; i < 3 ; i++)
41
{
42
int indis = (int)(Math.random() * 3); //
43
rastgele
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
switch(indis)
{
case 0:
h[indis] = new Bitki(); // upcasting
nesneAl(h[indis]);
break;
case 1:
h[indis] = new Hayvan(); // upcasting
nesneAl(h[indis]);
break;
case 2:
h[indis] = new Insan(); // upcasting
nesneAl(h[indis]);
break;
}
}
}
}
Ekran çıktısı:
Insan Sınıfı
1
Bitki Sınıfı
2
Hayvan
3
Sınıfı
Ekran çıktısı 2:
Hayvan
1
Sınıfı
2
Bitki Sınıfı
3
Insan Sınıfı
Örneğimizde bir Geç Bağlama olayı gösterilmiştir. Canli sınıfından 3 elemanlı
nesne dizisi üretiliyor. Daha sonra for döngümüz 3 kere dönüyor. Bu dönü
içerisinde her seferinde bir rastgele sayı üretiliyor. Bu üretilen rastgele
sayı switch içerisine koyuluyor ve kontrol yapılıyor. Sayımızın 0-1-2 olmasına
göre farklı referanslardan nesneler üretiliyor. Bu referanslar her çalışma
anında rastgele olarak belirleniyor. Her döngüde belirlenen indisli
nesne, nesneAl() metoduna gönderiliyor ve gelen nesneye göre yaz() metodları
çağırılıyor. Programımızı 2 kere çalıştırdık ve çıktıların farklı olduğunu gördük.
İşte bu nesnelerin çalışma anında belirlenmesine Geç Bağlama deniliyor.
Istisnalar:
!
Eğer geç bağlama olmasını istemiyorsak, ana sınıftaki istenilen
metodu final tanımlarız. Kalıtım konusunda,final anahtar
kelimesinin override etmeyi engellediğini söylemiştik. Bir metod alt
sınıflar tarafındanoverride edilmezse, parametre olarak gelen
nesnenin mi, yoksa parametre tipindeki nesnenin mi metodunun
çalıştırılacağı düşünülmez.
Polimorfizm anlatırken instanceof anahtar kelimesinden
bahsetmiştik. Polimorfizm ile buna artık gerek kalmasa da, bu konuyu da bir
sonraki dersimizde anlatacağız.
Ders 78 - Instanceof İle Tip Kontrolü
Bu anahtar kelime, nesnelerin hangi sınıftan oluşturulduğunu bulmaya
yardımcı olur. Örnek üzerinde göstererek anlatalım.
//C.java - 09.04.2014
1
2
class A
3
{
4
}
5
class B
6
{
7
}
8
class C
9
{
10
public static void main(String[]
11
args)
12
{
13
A a1 = new A();
14
B b1 = new B();
15
System.out.println(a1 instanceof
16
A);
17
System.out.println(b1 instanceof
18
B);
19
}
20
}
Ekran çıktısı:
1
true
2
true
Bu örnekte main metodumuzda, A sınıfından a1 nesnesini, B sınıfından
da b1 nesnesini oluşturduk. Bub1 nesnesi, A sınıfından oluşturulmamıştır. Alt
satırlarda da her iki çıktımız true değerini verecektir.
Çünkü a1ve b1 nesneleri, instanceof kelimesinden sonraki yazılmış sınıflardan
türemişlerdir.
Peki, sınıflarımız eğer kalıtım yoluyla türetilmişlerse nasıl bir mantık olacak?
Örnek üzerinde anlatalım.
1
//D.java - 09.04.2014
2
3
class A
4
{
5
}
6
class B extends A
7
{
8
}
9
class C extends B
10
{
11
}
12
class D extends B
13
{
14
public static void main(String[]
15
args)
16
{
17
A a1 = new A();
18
B b1 = new B();
19
C c1 = new C();
20
D d1 = new D();
21
System.out.println(a1 instanceof
22
B);
23
System.out.println(b1 instanceof
24
B);
25
System.out.println(c1 instanceof
26
A);
27
System.out.println(b1 instanceof
28
C);
29
30
31
System.out.println(c1 instanceof
A);
System.out.println(c1 instanceof
B);
System.out.println(d1 instanceof
B);
System.out.println(d1 instanceof
A);
}
}
Ekran çıktısı:
1
false
2
true
3
true
4
false
5
true
6
true
7
true
8
true
Bu örneğimizde temel mantık şu şekildedir. Örneğin; D sınıfını, B'den
türetmişiz. B sınıfını da yukarıdaA'dan türetilmiştir. Dolayısıyla D sınıfından
oluşturacağımız bir nesne, aynı zamanda A sınıfının da bir örneğidir (instance).
Kalıtım konusundaki kullanımı ise bu şekildedir.
Yukarıdaki örnekte mantığını anlattık. Şimdi de yukarıdaki sınıfların içini
doldurarak bir örnek yapalım ve ifyapılarını da kullanalım.
1
//D.java - 09.04.2014
2
3
class A
4
{
5
public int aSayi = 5;
6
}
7
class B extends A
8
{
9
public int bSayi = 6;
10
}
11
class C extends B
12
{
13
public int cSayi = 7;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
}
class D extends B
{
public static void main(String[] args)
{
A a1 = new A();
B b1 = new B();
C c1 = new C();
D d1 = new D();
if(c1 instanceof A)
{
System.out.println("c nesnesi A sınıfının elemanına
erişebilir:");
System.out.println(c1.aSayi);
}
else
System.out.println("c1 nesnesi aSayi değişkenine
erişemedi");
if(b1 instanceof D)
System.out.println("b1 nesnesi, D sınıfına erişebilir");
else
System.out.println("b1 nesnesi D sınıfına erişemez");
}
}
Ekran çıktısı:
c nesnesi A sınıfının elemanına
1
erişebilir:
2
5
3
b1 nesnesi D sınıfına erişemez
Örneğimizde c1 nesnesi aynı zamanda A sınıfının bir örneği olduğu
için if şartımıza girecektir ve aSayideğişkenini yazacaktır. b1 nesnesi
ise D sınıfının bir örneği olmadığı için else şartına girecektir.
instanceof anahtar kelimesi ile bir değişkenin ait olduğu sınıfı şu şekilde
karşılaştırabiliriz. Örnek verirsek;
1
//Karsilastirma.java - 09.04.2014
2
3
class Karsilastirma
4
5
6
7
8
9
10
11
12
{
public static void main(String[] args)
{
String deneme = "ElektroArge";
System.out.println(deneme instanceof
java.lang.String);
}
}
Ekran çıktısı:
1
true
String, bir sınıf olduğu için deneme adlı değişkenimiz
aslında String sınıfından türemiştir. Karşılaştırırken
ise java.lang.String şeklinde sınıfımızı yazıyoruz.
Aynı şekilde aşağıdaki gibi bir karşılaştırma da yapabiliriz. Bu da true değeri
döndürecektir. Stringharicindeki değişken tiplerimizi aşağıdaki gibi
tanımlamak zorundayız. Çünkü String sınıfı, diğer tiplerden farklıdır.
Yukarıda String değişken tanımlamıştık. Fakat String haricindeki
değişkenleri, new ile nesne oluşturarak yapmalıyız.
//Karsilastirma2.java - 09.04.2014
1
2
class Karsilastirma2
3
{
4
public static void main(String[] args)
5
{
6
Integer deneme = new Integer(4);
7
System.out.println(deneme instanceof
8
java.lang.Integer);
9
}
10
}
11
12
GETCLASS METODU İLE NESNENİN SINIFINI ÖĞRENME
Yukarıdaki karşılaştırmayı yapmanın bir yolu daha var. O
da getclass() metodudur. Bu metot, yalnız başına kullanıldığında nesnenin ait
olduğu sınıfı verir.
Şimdi basit bir örnek verelim ve kullanımını görelim.
1 package paket;
2 //D.java - 09.04.2014
3
4 class A
5 {
6 }
7 class B
8 {
9 }
10class D extends B
11{
12 public static void main(String[] args)
13 {
14
A a1 = new A();
15
B b1 = new B();
16
D d1 = new D();
17
System.out.println(d1.getClass().equals(A.class));
18
System.out.println(b1.getClass().equals(A.class));
19
System.out.println(a1.getClass().equals(A.class));
20
System.out.println(a1.getClass());
21
System.out.println(b1.getClass());
22
System.out.println(d1.getClass());
23 }
24}
25
26
Ekran çıktısı:
false
false
1
true
2
class
3
paket.A
4
class
5
paket.B
6
class
paket.D
Koda baktığımız zaman az çok anlıyoruz. İlk 3 satır bizim işimize yarayan
satırlar. Son 3 satırı isegetclass() metodunun yalnız başına ne iş yaptığını
göstermek için yazdık. İlk satırı ele alalım.
d1.getclass() diyerek d1'in olduğu sınıfı elde ediyoruz. equals() metodunun
içerisine de karşılaştıracağımız sınıfı yazıyoruz. Metodun içerisine yazdığımız
ifadeyi sınıfadı.class yapısı ile yazıyoruz. Eğer aynı sınıflardansa true değerini,
değilse false değerini elde ediyoruz.
Yalnız başına getclass() metodu ise, çıktıdaki son satırlarda da gördüğümüz
gibi sınıfın adını veriyor. Bunu paket adı ile beraber yazarak bize veriyor.
Istisnalar:
!
Java'da tüm sınıflar Object sınıfından türediği için, herhangi bir
nesnemiz aynı azamanda Object sınıfının bir örneğidir. Dolayısıyla
bir alt sınıf, aynı zamanda tüm üst sınıflarının bir örneği sayılır.
Fakat üst sınıflardan oluşturulan nesneler, alt sınıfların bir
örneği sayılmazlar
Ders 79 - Math Sınıfına Giriş
C dili ile biraz uğraştıysanız, bu sınıfa yabancı değilsiniz demektir. Math sınıfı,
Java'da matematiksel işlemler yapmaya yarayan bir sınıftır. Bünyesinde
matematiksel işlemler yapan metodları barındırır. Mesela;üs alan bir işlem
yapacaksak, bunu döngüler ile uzun uzun yapmaktansa, tek bir metot ile
yapabilirsiniz. Mathsınıfı bize bu metotları sağlar. Şimdi sıradaki derslermizle
bu metotları örnek üzerinden anlatalım.
Ders 80 - Math.pow Metodu İle Sayının Üssünü Alma
Bu metot,üs alma işlemi yapar. 2 parametre alır. İlk parametre üssü alınacak
sayıdır. Diğer parametre ise üssün derecesidir.
1
//MathSinifiOrnekler.java - 09.04.2014
2
3
class MathSinifiOrnekler
4
{
5
public static void main(String[] args)
6
{
7
8
9
10
11
12
13
System.out.println(Math.pow(3, 5));
int a = (int)Math.pow(2, 4); // cast işlemi
yapıldı
System.out.println(a);
}
}
Bu örnekte ilk satırda doğrudan 3'ün 5. kuvvetini alarak ekrana yazdırdık.
Sonuç double türünde ondalık bir sayı oldu. Normalde sonuç int tipinde olması
gerekirdi. Çünkü sonuç 243'tür. Buradan anlıyoruz
ki Mathsınıfından double türünden değerler dönüyor. Bir alt satırda da 2'nin 4.
kuvvetinin sonucunu int'e cast ettik. Eğer etmeseydik doğrudan int
a değişkenine atsaydık, hata verecekti. Sonuç double döndüğü için
doğrudanint değişkenine atayamadık. Buradan şunu anlıyoruz.
Istisnalar:
!
Math sınıfında işlem sonucunda dönen değerler, double türünde
olabileceğinden sonucu int'e cast etmek gerekir.
Ders 81 - Math.sqrt Metodu İle Sayının Karekökünü Alma
Bu metot, bir sayının karekökünü bulur. Dolayısıyla 1 parametre alır. Bu
da double türünden değer döndürür. O yüzden bir değişkene
atacaksak, cast etmemiz gerekir. Eğer sonucu yine double türünde bir
değişkene atacaksak, cast işlemine gerek yoktur.
1 //MathSinifiOrnekler.java - 09.04.2014
2
3 class MathSinifiOrnekler
4 {
5
public static void main(String[] args)
6
{
7
System.out.println(Math.sqrt(25));
8
int b = (int)Math.sqrt(25);
9
System.out.println(b);
10
System.out.println(Math.sqrt(50));
11
}
12 }
13
14
Ekran çıktısı:
1 5.0
2 5
3 7.0710678118654755
Bu metottan da double türünde sonuç döndü. 2. satırda ise cast etmek zorunda
kaldık. Son satırda da 50'nin tamsayı olarak karekökü olmadığı için küsüratlı
bir sonuç elde ettik.
Ders 82 - Math.abs Metodu İle Sayının Mutlak Değerini Alma
Bu metot bir sayının mutlak değerini alır. Negatif bir sayıyı pozitife çevirip
gösterir. Pozitif bir sayıyı ise aynen yazar.
1
//MathSinifiOrnekler.java - 09.04.2014
2
3
class MathSinifiOrnekler
4
{
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args)
{
System.out.println(Math.abs(-40));
int b = Math.abs(-40); // cast'e gerek
yok
System.out.println(b);
System.out.println(Math.abs(20));
}
}
Ekran çıktısı:
1
40
2
40
3
20
Bu metotta bir istisnayı gördük. Sonucu doğrudan int değişkenine atabiliriz.
Cast işlemine gerek yoktur. Sonuç int tipinde döndü, çünkü pozitif sayıyı da
aynen yazdı. Eğer bir int tipinde değil de double tipinde bir sayının mutlak
değerini almaya çalışsaydık, o zaman cast etmemiz gerekirdi. Fakat diğer
metotlarda int tipinde bir sayıyla bile işlem yapsak sonucu double türüne
çeviriyordu.
Biz int tipindeki bir değişkene atamaya çalıştığımız için hep cast işlemi yaptık.
Eğer int b değil de double badlı değişkene atsaydık cast işlemine gerek
kalmayacaktı. Amacımız bazı durumlarda double tipinde sonuç döndüğünü
göstermektir.
Ders İçinde Yazılmış Tüm Programlar ve Kodları Ektedir:
Ders 83 - Math.floor Metodu İle Sayıyı Alt Değere Yuvarlama
floor kelimesi İngilizcede zemin anlamına geldiği için bu metodun ne iş
yaptığını kestirebilirsiniz. Verilen bir tamsayıyı bir alttaki değere yuvarlar.
1 //MathSinifiOrnekler.java - 09.04.2014
2
3 class MathSinifiOrnekler
4 {
5
public static void main(String[] args)
6
{
7
System.out.println(Math.floor(5.4));
8
int b = (int)Math.floor(7.501);
9
System.out.println(b);
10
double c = Math.floor(8.0001);
11
System.out.println(c);
12
System.out.println(Math.floor(9));
13 }
14 }
15
16
Ekran çıktısı:
1
5.0
2
7
3
8.0
4
9.0
Bu metot, bir nevi sayının virgülden sonraki kısmını atar. Bu metot
da double türünde sonuç döndürür. Örnekte de görüldüğü gibi b değişkenine
atarken cast etmek zorunda kaldık. Eğer sayımız 7.501 değil de 7 olsaydı yine
onu 7.0 olarak çevirecekti ve yine cast etmemiz gerekecekti. Alt satırda da
doğrudan doubletipindeki değişkene atadığımız için cast işlemine gerek
kalmadı. İlk satırdaki gibi doğrudan yazdırdığımız zaman, zaten herhangi bir
işleme gerek kalmadan sonucu yazıyor.
Ders 84 - Math.ceil Metodu İle Sayıyı Üst Değere Yuvarlama
Bu metot, Math.floor metodunun aksine, sayıyı üst değere yuvarlar. Bir nevi
virgülden sonraki kısmı atar ve kalan sayıyı 1 artırır.
1 //MathSinifiOrnekler.java - 09.04.2014
2
3 class MathSinifiOrnekler
4 {
5
public static void main(String[] args)
6
{
7
System.out.println(Math.ceil(7.0001));
8
int b = (int)Math.ceil(7.9999);
9
System.out.println(b);
10
System.out.println(Math.ceil(7));
11 }
12 }
13
14
Ekran çıktısı:
1
8.0
2
8
3
7.0
Bu metot da double tipinde değer döndürür. Onu göstermek için int tipinde bir
değişkene attık. Görüldüğü gibi 7.0001 bile olsa onu 8'e tamamlıyor, yani
yuvarlıyor. Eğer son satırdaki gibi sadece 7 sayısını verirsek onu yuvarlamadan
bırakıyor. Görüldüğü gibi 7'yi 7.0 olarak yazıyor. Bu da double tipinde değer
döndüğünü gösteriyor.
Ders 85 - Math.max Metodu İle Büyük Sayıyı Bulma
Adından da anlaşıldığı üzere, verilen sayılardan büyüğünü bulan metottur. 2
parametre alır.
1
//MathSinifiOrnekler.java - 09.04.2014
2
3
class MathSinifiOrnekler
4
{
5
6
7
8
9
10
11
12
13
14
15
16
17
static void yaz(int a, int b)
{
System.out.println(Math.max(a, b));
}
public static void main(String[] args)
{
MathSinifiOrnekler.yaz(55, 56); // metoda parametre
gönderdik
System.out.println(Math.max(4, 5));
System.out.println(Math.max(4, 4.0001));
}
}
Ekran çıktısı:
1
56
2
5
3
4.0001
Bu örnekte gördüğümüz gibi Math sınıfının metotlarını doğrudan kullanmak
yerine parametre geçirerek de kullanabiliriz. Ayrıca bu örnekte son yazdığımız
kodda küsüratlar sayesinde sayımız 4'ten büyük olmuştur.
Ders 86 - Math.min Metodu İle Küçük Sayıyı Bulma
Bu metot, Max metodunun tersine verilen iki sayıdan küçük olan sayıyı bulan
metottur. Metot, 2 parametre alır.
1
//MathSinifiOrnekler.java - 09.04.2014
2
3
class MathSinifiOrnekler
4
{
5
static void yaz(int a, int b)
6
{
7
System.out.println(Math.min(a, b));
8
}
9
public static void main(String[] args)
10
{
11
MathSinifiOrnekler.yaz(55, 56); // metoda parametre
12
gönderdik
13
System.out.println(Math.min(4, 5));
14
15
16
17
System.out.println(Math.min(4, 4.0001));
}
}
Ekran çıktısı:
1
55
2
4
3
4.0
Daha önce max metodu için yaptığımız örneği bu sefer min metodu için yaptık.
Değerlere baktığımızda metodumuzun bize verilen sayıların en küçüğünü
bulduğunu görüyoruz. Hem yaz() metodunu çağırarak yaptık hem de
doğrudan Math.min() metodu ile işlem yaptık.
Ders 87 - Math.random Metodu İle Rastgele Sayı Üretme
Bu metot, rastgele sayılar üretmek için kullanılır. Bu metot da double türünde
değer döndürür ve 0.0 ile 1.0 arasında değer üretir. Bu konuya birkaç örnek
verelim.
1 //RandomSinifi.java - 09.04.2014
2
3 class RandomSinifi
4 {
5
public static void main(String[] args)
6
{
7
System.out.println(Math.random());
8
}
9 }
10
11
Ekran çıktısı:
1 0.025176312544407664
Dediğimiz gibi bu metot, 0-1 arasında double bir sayı üretti. Peki, bu sayı nasıl
işimize yarayacak? Aşağıdaki kod parçasını inceleyelim ve bu metodu nasıl
faydalı bir şekilde kullanırız onu görelim.
int sayi = (int)(Math.random() * 10);
1
// double türünde sayı üretileceğinden int'e cast etmek
2
gerekir
3
System.out.println(sayi);
Math.random() ile rastgele bir sayı ürettik. Üretilen değeri 10 ile çarpmamızın
sebebi, bu metodun 0 ile 1 arasında double türünde değer üretmesidir. Bunu 10
ile çarparak virgülü sola kaydırırız. Mesela; metottan çıkan değer 0.654323 ise
10 ile çarptığımızda 6.554323 olur. Daha sonra sonucu int'e cast edince
başındaki6 sayısını alır.
Sonuç olarak bu fonksiyon 0 ile 10 arasında değer üretecektir. Biz bu
fonksiyonun sonuna +10 eklersek; 10 ile 20 arasında sayı üretecektir. Buna 20
dahil değildir.
Bir örnek verirsek:
//RandomSinifi2.java - 09.04.2014
1
2
class RandomSinifi2
3
{
4
public static void main(String[] args)
5
{
6
System.out.println(Math.random());
7
System.out.println((int)(Math.random() * 15));
8
//0 - 15 arasında sayı üretecektir
9
System.out.println((int)(Math.random() * 15 +
10
20));
11
//0 - 35 arasında sayı üretecektir
12
}
13
}
14
15
Ekran çıktısı:
1 0.5205707499643846
2 1
3 34
Yukardaki örnekte, metodumuzu hem çarpıyoruz hem de sonuca değer
ekliyoruz. Böylece üretilecek sayımızın eleman kümesini genişletiyoruz.
Bu anlattıklarımıza, döngüleri ve dizileri de kullanarak bir örnek verelim.
//RandomSayi.java - 09.04.2014
1
2
import java.util.Random;
3
4
public class RandomSayi
5
{
6
public static void main(String[] args)
7
{
8
int dizi[] = new int[6];
9
Random r = new Random();
10
for (int a = 0; a < dizi.length ; a++)
11
{
12
dizi[a] = r.nextInt(100);
13
System.out.println("Dizinin " + (a + 1) + ". elemanı: " +
14
dizi[a]);
15
}
16
}
17
}
18
19
Ekran çıktısı:
Dizinin 1. elemanı:
40
Dizinin 2. elemanı:
1
84
2
Dizinin 3. elemanı:
3
38
4
Dizinin 4. elemanı:
5
14
6
Dizinin 5. elemanı:
48
Dizinin 6. elemanı:
11
Bu örnekte 6 elemanlı dizimize, for döngüsü içerisinde rastgele 0 ve 100
arasında sayılar atadık. Daha sonra bu atadığımız dizi elemanlarını ekrana
yazdırdık.
Son olarak basit bir örnekle bitirelim.
//MathSinifiOrnekler.java 09.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MathSinifiOrnekler
{
public static void main(String[]
args)
{
for (int i = 0 ; i < 4 ; i++)
{
int a = (int)(Math.random() *
10);
System.out.println(a);
}
}
}
Ekran çıktısı:
1
4
2
9
3
9
4
3
Istisnalar:
!
Math sınıfı, java.lang paketinden türediği için bu Math sınıfını
ayrıca import etmeye gerek yoktur. Çünküjava.lang paketi zaten
Java programlarında otomatik olarak import edilmiştir.
RANDOM SINIFI İLE RASTGELE SAYI ÜRETME
Rastgele sayı üretebilmek için Math sınıfının yanında Random sınıfı da
kullanılır. Random sınıfı, sadece inttüründe değil float, byte, double gibi
türlerde de sayı üretebilir. Rastgele sayı üretmenin bir diğer yolu olduğu için bu
başlık altında kısaca değineceğiz.
Bu sınıfı kullanmak için öncelikle sınıfı tanımladığımız yerin üst kısmına, paket
isminden sonra şu sınıfıimport ediyoruz.
[code2=]import java.util.Random;[/code2] // Random sınıfı import edildi
Paket tanımlamaları hep bu kısma yapılır.
İlk olarak Random sınıfından bir nesne oluşturuyoruz. Şimdi oluşturulan bu
nesneden bir sayı üretiyoruz.
Random r = new Random(); // random sınıfından r adında bir nesne
1
oluşturduk
2
int a = r.nextInt(10); // bu r nesnesinden int tipinde sayı üretiyoruz
Random sınıfından r adında bir nesne oluşturuyoruz ve r nesnesi
üzerinden nextInt() metoduna erişiyoruz. Bu metot, bize int tipinde rastgele bir
sayı üretecektir.
Burada parantez içerisinde 10 yazmamızın sebebi, 0'dan 10'a kadar değerler
üretmesini istememizdir. Fakat buna 10 dahil değildir, 0 dahildir. Hangi değere
kadar sayı üretilmesini istiyorsak, parantez içerisine onu yazarız. Eğer parantez
içerisini boş bırakırsak -2147483648 ve +2147486647 arasındaki
bütün int değerlerini üretir. Diğer türlerde sayı üretmek istiyorsak
kullanacağımız kodlar:
long l = r.nextLong();
// long tipinde bir sayı üretir
1
float f = r.nextFloat();
// float tipinde bir sayı üretir
2
double d = r.nextDouble(); // double tipinde rastgele bir sayı
3
üretir
Rastgele sayımızı bu şekilde Random sınıfından türetilen nesne
üzerinden oluşturuyoruz. Programımızı her çalıştırdığımızda istenilen
tipte rastgele bir sayı üretecektir.
Bu r nesnesi üzerinden farklı farklı metodlara erişebiliriz. Bu metotların listesi
şu şekildedir:
Buradaki metotlardan, rastgele sayı üreten nextDouble(), nextFloat() gibi
metotları inceleyeceğiz.
Şimdi bütün tipleri kullanarak örnek yapalım.
//RandomSinifi3.java - 09.04.2014
1
2
import java.util.Random;
3
4
class RandomSinifi3
5
{
6
public static void main(String[] args)
7
{
8
Random r = new Random();
9
System.out.println("Int: " + r.nextInt());
10
// 0 ile 10 arasında üretecektir
11
12
System.out.println("Int: " + r.nextInt());
13
System.out.println("Boolean: " +
14
r.nextBoolean());
15
System.out.println("Double: " +
16
r.nextDouble());
17
System.out.println("Float: " + r.nextFloat());
18
System.out.println("Long: " + r.nextLong());
19
System.out.println("Gaussian: " +
20
r.nextGaussian());
21
}
22
}
Ekran çıktısı:
Int: 554977118
1
Int: -1875198449
2
Boolean: false
3
Double:
4
0.29761422254107595
5
Float: 0.54041606
6
Long: 8923612717938646514
7
Gaussian: 2.1147448804741766
Yukardaki örneğimizde her tipte rastgele bir sayı ürettik. Gaussian tipi, bir
çeşit double veri tipidir. Programımızı her çalıştırdığımızda bu değerler
değişecektir.
Başka bir örnek verelim.
1
//RandomSayi2.java - 09.04.2014
2
3
import java.util.Random;
4
5
public class RandomSayi2
6
{
7
public static void main(String[] args)
8
{
9
int sayi = 5 ,deger = 0;
10
Random r = new Random();
11
while(true)
12
{
13
int i = r.nextInt(11);
14
if(i != sayi)
15
deger++;
16
else
17
{
18
System.out.println("Sayı " + deger + ". denemede
19
bulundu");
20
break;
21
}
22
}
23
}
24
}
25
Ekran çıktısı:
Sayı 8. denemede
1
bulundu
Bu örnekte while(true) ile sonsuz döngüye girdik. Daha sonra 0 ile 11 arasında
bir değer üreterek bunu i değişkenine attık. Program başlangıcında
belirlediğimiz sayi değişkenini, kaçıncı denemede bulacağını ifdöngüleri ile
kontrol ettik. Rastgele üretilen sayı ile başlangıçta belirlediğimiz sayı aynı
olduğunda break; ile döngüden çıktık.
Son bir örnek verelim.
//RandomSinifi4.java - 09.04.2014
1
2
import java.util.Random;
3
4
class RandomSinifi4
5
{
6
public static void main(String[] args)
7
{
8
Random r = new Random();
9
for(int i = 0 ; i < 3 ; i++)
10
{
11
int sayi1 = r.nextInt(6);
12
sayi1 += 1;
13
int sayi2 = r.nextInt(6);
14
sayi2 += 1;
15
System.out.println("Zarda gelen
16
sayılar: ");
17
System.out.println(sayi1 + " - " +
18
sayi2);
19
}
20
}
21
}
22
Ekran çıktısı:
1
Zarda gelen
2
sayılar:
3
5-1
4
5
6
Zarda gelen
sayılar:
3-2
Zarda gelen
sayılar:
1-2
Örneğimizde for döngümüz ile 3 kere zar
atıyoruz. sayi1 ve sayi2 değişkenlerini 1 artırmamızın sebebi ise şudur.
Eğer nextInt() metodu ile 0 değeri üretilirse, bunu 1 yapmamız gerekiyor.
Çünkü zarlarda 0 sayısı bulunmaz. Üst sınıf olarak ise 6 verdik. En fazla 5
sayısı üretilir. Artırma işlemi ile bu yine 6'ya çıkar ve en fazla 6 sayısı üretilir.
Ders 88 - Math.toDegrees Metodu İle Radyanı Dereceye Çevirme
Matematik sınıfımızın bu metodu radyanı dereceye çevirir. Parametre olarak
aldığı double değerinderece karşılığını geriye döndürür.
//MathSinifiOrnekler.java - 09.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
public class MathSinifiOrnekler
{
public static void main(String[] args)
{
System.out.println("0.5 Radyan " + Math.toDegrees(0.5) + "
derecedir.");
System.out.println("1 Radyan " + Math.toDegrees(1) + "
derecedir.");
System.out.println("1.5 Radyan " + Math.toDegrees(1.5) + "
derecedir.");
}
}
Ekran çıktısı:
1
0.5 Radyan 28.64788975654116
2
derecedir.
3
1 Radyan 57.29577951308232
derecedir.
1.5 Radyan 85.94366926962348
derecedir.
Yukarıdaki örneğimizde radyan cinsinden değerleri derece cinsine çevirdik.
Geriye dönen değerlerimizindouble değer olduğuna dikkat ediniz.
Ders 89 - Math.toRadians Metodu İle Dereceyi Radyana Çevirme
Matematik sınıfımızın bize sağladığı bu metot, toDegrees metoduna benzer.
Parametre olarak aldığıderece cinsinden değeri radyan cinsine çevirir.
//MathSinifiOrnekler.java - 09.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
public class MathSinifiOrnekler
{
public static void main(String[] args)
{
System.out.println("0 Derece " + Math.toRadians(0) + "
radyandır.");
System.out.println("45 Derece " + Math.toRadians(45) + "
radyandır.");
System.out.println("90 Derece " + Math.toRadians(90) + "
radyandır.");
}
}
Ekran çıktısı:
0 Derece 0.0 radyandır.
1
45 Derece 0.7853981633974483
2
radyandır.
3
90 Derece 1.5707963267948966
radyandır.
Yukarıda verdiğimiz örnekte 45 ve 90 dereceyi radyan cinsine çevirmek
için toRadians metodumuzu kullandık. Metodumuzun bize döndürdüğü
değerin yine double tipte olduğuna dikkat ediniz.
Ders 90 - Math.sin Metodu İle Sinüs Bulma
Matematik sınıfımızın trigonometrik metotlarından biri olan sin metodu
içerisine, parametre olarak aldığıradyan cinsinden açının sinüsünü döndürür.
1 //MathSinifiOrnekler.java - 09.04.2014
2
3 public class MathSinifiOrnekler
4 {
5 public static void main(String[] args)
6
{
7
System.out.println(Math.sin(Math.toRadians(0)));
8
System.out.println(Math.sin(Math.toRadians(90)));
9
System.out.println(Math.sin(Math.toRadians(45)));
10 }
11}
12
13
Ekran çıktısı:
1 0.0
2 1.0
3 0.7071067811865475
Örneğimizde matematik sınıfımızın sin ve toRadians metotlarını kullandık ve
metodumuza parametre olarak radyan cinsinden 0.45 ve 90 dereceyi gönderdik.
Derece cinsinden bu değerleri radyan cinsine çevirmek
için toRadians metodunu kullandık. Sin(0)'ın matematiksel değeri 0, Sin(90)'ın
matematiksel değeri 1, Sin(45)'in matematiksel değeri ise yaklaşık olarak
1/karekök 2'dir.
2. satırı ele alırsak, 90 dereceyi radyana çevirir ve çıkan sonucu sin metoduna
parametre olarak göndermiş olur.
Ders 91 - Math.asin Metodu İle Ters Sinüs Bulma
Bu metot, sin metodunun tersine parametre olarak sinüs değerini alır ve bu
sinüs değerine karşılık gelen açıyı yine radyan cinsinden gönderir.
1 //MathSinifiOrnekler.java - 09.04.2014
2
3 public class MathSinifiOrnekler
4 {
5 public static void main(String[] args)
6
{
7
System.out.println(Math.toDegrees(Math.asin(0)));
8
System.out.println(Math.toDegrees(Math.asin(1)));
9
System.out.println(Math.toDegrees(Math.asin(0.7071067811865476)));
10 }
11}
12
13
Ekran çıktısı:
1 0.0
2 90.0
3 45.00000000000001
Örneğimizde asin metodumuza daha önceki örneğimizden elde ettiğimiz açısal
değerleri gönderdik ve gelen açıyı derece cinsine çevirmek
için toDegrees metodunu kullandık. Ekran çıktımızda da görüldüğü gibi 0,90
ve 45 dereceyi metodlarımızla elde ettik.
2. satırı ele alırsak, 1'e karşılık gelen sinüs açısı 90'dır. 90'ı radyana çevirir ve
elde edilen sonucutoDegrees metoduna gönderir. Yani sinüs değeri alır ve
radyana çevirir.
Ders 92 - Math.cos Metodu İle Cosinüs Bulma
Bu metodumuz içerisine parametre olarak aldığı radyan cinsinden
değerin cosinüs değerini döndürür. Bir derecenin cosinüs değerini öğrenmek
istiyorsak, ilk olarak bu dereceyi radyana çevirmek gerekir. Çünkü bu metod
radyanı parametre olarak alır.
1 //MathSinifiOrnekler.java - 09.04.2014
2
3 public class MathSinifiOrnekler
4 {
5 public static void main(String[] args)
6
{
7
System.out.println(Math.cos(Math.toRadians(0)));
8
System.out.println(Math.cos(Math.toRadians(60)));
9
System.out.println(Math.cos(Math.toRadians(45)));
10 }
11}
12
13
Ekran çıktısı:
1 1.0
2 0.5000000000000001
3 0.7071067811865476
Örneğimizde öncelikle derece cinsinden değerleri radyan cinsine çevirmek
için toRadians metodunu kullandık. Daha sonrasında bu
değerlerin cosinüs değerlerini bulmak için cos metodunu kullandık.
Ders 93 - Math.acos İle Ters Cosinüs Bulma
Bu metot yine asin metodunda olduğu gibi içerisine parametre olarak
bir cosinüs değeri alır ve geriye bu cosinüs değerine ait radyan cinsinden açıyı
gönderir.
1 //MathSinifiOrnekler.java - 09.04.2014
2
3 public class MathSinifiOrnekler
4 {
5 public static void main(String[] args)
6
{
7
System.out.println(Math.toDegrees(Math.acos(0)));
8
System.out.println(Math.toDegrees(Math.acos(1)));
9
System.out.println(Math.toDegrees(Math.acos(0.7071067811865476)));
10 }
11}
12
13
Ekran çıktısı:
1
90.0
2
0.0
3
45.0
Örneğimizde acos metodumuzua 0,1 ve 0.7071067811865476 değerlerini
parametre olarak gönderdik. Dönen sonucu ise radyandan dereceye çevirmek
için toDegrees() metodunu kullandık. Ekran çıktımızda da görüldüğü gibi
sonuç olarak ise 90.0 ve 45 değerlerini elde ettik.
Ders 94 - Math.PI İle Pi Sabitini Kullanma
public static final double PI; değişkeni tanımlamak ile aynıdır. Math sınıfının
içerisinde de static ve finalolarak tanımlanmıştır. Hem değeri değiştirilemez
hem de sadece sınıf adı ile erişilebilir. Her ne kadar metot olarak gözükmese de,
yani bir parametre almasa da pi sayısının bu sınıfta yer aldığını göstermek için
anlatıyoruz.
Kısa bir örnek verelim.
//MathSinifiOrnekler.java 1
09.04.2014
2
3
public class MathSinifiOrnekler
4
{
5
public static void main(String[]
6
args)
7
{
8
System.out.println(Math.PI);
9
}
10
}
11
Ekran çıktısı:
1 3.141592653589793
Pi değişkeninin değeri bu sınıf içerisinde yer alır.
Ders 95 - Logaritma Metodları
Matematik sınıfımız içerisinde üç tane logaritma metodu bulunmaktadır. Hepsi
genel olarak logaritma döndürmesine rağmen farklılık logaritma tabanlarından
gelir. Metotlarımız şöyledir:

Double: log(double deger): deger ile gönderilen değerin doğal
logaritmasını(e tabanında) döndürür.

Double: log10(double deger): deger ile gönderilen değerin 10
tabanındaki logaritmasını döndürür.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Double: log1p(double deger): deger ile gönderilen değerin 1
fazlasının doğal logaritmasını döndürür.
//MathSinifiOrnekler.java - 09.04.2014
public class MathSinifiOrnekler
{
public static void main(String[] args)
{
System.out.print("2.718281828459 sayısının doğal
logaritması:");
System.out.println(Math.log(2.718281828459));
// e ≈ 2.718281828459 ve ln(e) = 1
System.out.print("10 tabanında 5'in logaritmik değeri: ");
System.out.println(Math.log10(5));
System.out.print("10 tabanında 10'un logaritmik değeri: ");
System.out.println(Math.log10(10));
System.out.print("(1.7 + 1) 'in doğal algoritması: ");
System.out.println(Math.log1p(1.7));
}
18
19
}
Ekran çıktısı:
2.718281828459 sayısının doğal
1
logaritması:0.9999999999999832
2
10 tabanında 5'in logaritmik değeri: 0.6989700043360189
3
10 tabanında 10'un logaritmik değeri: 1.0
4
(1.7 + 1) 'in doğal algoritması: 0.9932517730102834
Örneğimizde tüm logaritma metodlarını kullandık. İlk bölümde doğal logaritma
almak için log() metodunu kullandık. İkinci bölümde ise, verdiğimiz değerlerin
10 tabanında logaritmasını aldık. Üçüncü bölümde verdiğimiz değerin 1
fazlasının doğal logaritmasını bulmak için log1p() metodunu kullandık.
Istisnalar:
!
Math sınıfının içerisindeki metodlar static'tir. O yüzden
doğrudan sınıf adını kullanarak metodlara erişebildik. Bir nesne
oluşturmaya ihtiyacımız olmadı.
Math sınıfına ait birçok metod vardır. Math sınıfında kullanılabilecek
metodların ne kadar çok olduğunu aşağıdaki resimde görebilirsiniz.
Ders 96 - String Sınıfına Giriş
Bu bölümde daha önce birçok yerde karşılaştığımız String sınıfını
açıklayacağız. String sınıfı, karakter katarları üzerinde işlem yapmayı
kolaylaştırmak için oluşturulmuştur. String, sınıfı, java.lang kütüphanesi
altında bulunur ve bize karakter dizeleri üzerinde işlem yapmamızı
kolaylaştıran zengin bir kütüphane sunar. Ayrıca String sınıfı
metotları, immutable metodlardır. Yani bu sınıfın metodları değiştirilemez.
String sınıfı miras alınarak, yeni bir sınıf türetilemez. String sınıfı metotları
genel olarak karakter dizelerini karşılaştırmak, karakter dizeleri içerisinde
arama yapmak, alt dizgeleri (sub-string) ayıklamak, karakter dizeleri
birleştirmek ve karakterleri büyütüp küçültmek gibi işlemlerde kullanılır.
String sınıfının kullanımına basit bir örnek verip daha sonra metotların
kullanımını açıklayalım.
//StringOrnek.java - 09.04.2014
1
2
public class StringOrnek
3
{
4
public static void main(String[] args)
5
{
6
char dizi[] = {'E', 'l', 'e', 'k', 't', 'r', 'o', 'a', 'r', 'g',
7
'e'};
8
String katar = new String(dizi);
9
String dizge = "String sınıfını öğreniyorum";
10
11
System.out.println(katar);
12
System.out.println("String sınıfını
13
öğreniyorum.");
14
System.out.println("JAVA " + dizge);
15
16
}
17
}
18
Ekran çıktısı:
1
Elektroarge
2
String sınıfını öğreniyorum.
3
JAVA String sınıfını
öğreniyorum
String sınıfı, karakter dizilerinin yaptıklarından daha fazlalarını yapabilirler.
Bu yüzden String sınıfı daha fazla kullanılır.
Örnekte oluşturduğumuz karakter dizisinin içeriğini bir String sınıfı nesnesine
gönderdik. Daha sonra bu nesneyi ekrana yazdırdık. İlk println() metoduyla
ekrana yazdırdığımız metni, ikinci println() metodundaString nesnesi
yardımıyla yazdırdık.
Ders 97 - String Nesnesinin Uzunluğu
Bir String nesnesinin uzunluğunu, yani taşıdığı karakter sayısını bulabilmek
için String sınıfının length()metodunu kullanırız. Bir örnekle bu metodu
açıklayalım.
//StringOrnek.java - 09.04.2014
1
2
public class StringOrnek
3
{
4
public static void main(String[] args)
5
{
6
String dizge = "String sınıfı örneği";
7
8
int a = dizge.length(); // uzunluğu bulundu
9
System.out.println("Karakter katarının uzunluğu: "
10
+ a);
11
12
}
13
}
14
15
Ekran çıktısı:
Karakter katarının uzunluğu:
1
20
Örnekte de görüldüğü gibi String nesnesinin uzunluğunu length() metodu
yardımıyla bulduk ve ekrana yazdırdık.
Ders 98 - Karakter Katarlarını Birleştirmek
Java'da karakter katarlarını (String) birleştirmek için iki yöntem kullanılır.
Bunlardan en çok kullanılanı ve birincisi + operatörü yardımıyla birleştirmektir.
İkincisi ise contact() metodu yardımıyla birleştirmektir.
+ OPERATÖRÜ İLE STRING İFADELERİ BİRLEŞTİRME
Daha önce de anlattığımız bu operatör, String ifadeleri birleştirir.
Ayrıca String ile bir değişkeni de birleştirebilir. Örnek verirsek:
//StringOrnek.java - 09.04.2014
1
2
public class StringOrnek
3
{
4
public static void main(String[]
5
args)
6
{
7
String d1 = "String";
8
String d2 = "Nesnesi";
9
String d3 = d1 + d2;
10
System.out.println(d3);
11
}
12
}
13
14
Ekran çıktısı:
1 StringNesnesi
Görüldüğü gibi örnekte d3 içerisinde d1 ve d2 değişkenlerinin
içeriklerini + operatörü yardımıyla birleştirip sakladık.
Aynı şekilde bir String ifadesi ile bir değişkeni de birleştirebiliriz. Buna da bir
örnek verelim.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//StringOrnek2.java - 09.04.2014
public class StringOrnek2
{
public static void main(String[] args)
{
ornek o1 = new ornek();
String d1 = "Okan";
String d2 = "Bilke";
int d3 = 3;
System.out.println(d1+ " " + d2 + " " + d3 + " " +
o1.islem());
}
}
class ornek
{
int islem()
{
return 4;
}
}
Ekran çıktısı:
Okan Bilke 3
1
4
Bu örnekte bir String ile değişkeni ve aynı zamanda da metottan dönen değeri
birleştirmeyi anlattık. Aralarda boşluk olması için " " ifadesini yazdık.
CONCAT METODU İLE STRING İFADELERİ BİRLEŞTİRME
Bir karakter katarını yani bir String'i başka bir String ile birleştirmenin diğer
bir yolu da concat()metodudur. Bunun da kullanımını gösterelim.
1
//StringOrnek3.java - 09.04.2014
2
3
public class StringOrnek3
4
{
5
public static void main(String[]
6
args)
7
{
8
9
10
11
12
13
14
String d1 = "String";
String d2 = "Nesnesi";
String d3 = d1.concat(d2);
System.out.println(d3);
}
}
Ekran çıktısı:
1 StringNesnesi
Örneğimizde iki String değişkenini birleştirdik. concat() metodunun farkı,
yalnızca String tipindeki değişkenleri birleştirebilir.
concat() metodu, referans olarak aldığı String tipteki değişkeni çağrıldığı
nesnenin içeriği ile birleştirir.String nesnesi ile bir değişkeni veya integer bir
değeri birleştirmek isteseydik, concat() metoduyla bu işlemi doğrudan yapmak
mümkün olmayacaktı. String nesnesi ile başka tipteki bir değişkeni + operatörü
yardımıyla birleştirebiliriz.
Ders 99 - String Nesnelerini Karşılaştırma
Java'da String nesnelerini karşılaştırırken diğer veri tiplerine göre değişik
metotlar kullanırız. En önemlisi iki String metodunun birbirine eşit olup
olmadığını kontrol ederken, == operatörünü String nesneleri üzerinde
kullanamayız.
Istisnalar:
!
Java'da String tipindeki iki veriyi == operatörü ile
karşılaştırdığımızda nesneleri kontrol eder. Eğer verimiz aynı, fakat
nesnelerimiz farklı ise hatalı sonuç verebilir. O yüzden
Java'da String tipindeki değişkenleri özel metotlar ile karşılaştırırız.
Örnek verirsek:
1
String a =
2
"Mehmet";
3
4
5
6
7
String b = "Sezer";
if(a==b)
{
// işlemler
}
Bu şekilde bir karşılaştırma hatalı sonuç verebilir.
Karşılaştırma metotları ve özellikleri şu şekildedir.
EQUALS VE EQUALSIGNORECASE METODLARI İLE STRİNG
NESNELERİ KARŞILAŞTIRMA
Java'da iki String nesnesinin birbirine eşit olup olmadığını kontrol etmek
için equals() veequalsIgnoreCase() metotlarını kullanırız.
equals() metodu, referans olarak aldığı String nesnesini, kendisini
çağıran String nesnesiyle karşılaştırır. Eğer iki String nesnesi de aynı
karakterleri aynı sırada içeriyorsa geriye true değer döndürür. İki Stringnesnesi
birbirine eşit değilse false değer döndürür. Bu metot harf
büyüklüğüe duyarlıdır. Yani okan ile Okanaynı değildir.
equalsIgnoreCase() metodu ise equals() metodunun yaptığı işlemlerin aynısını
yapar, fakat bu metodun büyük küçük harf duyarlılığı yoktur. Bu iki metodu
bir örnekle daha iyi açıklayalım.
1
//StringOrnek.java - 09.04.2014
2
3
public class StringOrnek
4
{
5
public static void main(String[] args)
6
{
7
String d1 = "Edirne";
8
String d2 = "İstanbul";
9
String d3 = "Edirne";
10
String d4 = "İSTANBUL";
11
12
System.out.println(d1 + " - " + d2 + " = " + d1.equals(d2));
13
System.out.println(d2 + " - " + d4 + " = " + d2.equals(d4));
14
System.out.println(d1 + " - " + d3 + " = " + d1.equals(d3));
15
System.out.println(d2 + " - " + d4 + " = " +
16
d2.equalsIgnoreCase(d4));
17
}
18
19
}
Ekran çıktısı:
Edirne - İstanbul = false
1
İstanbul - İSTANBUL =
2
false
3
Edirne - Edirne = true
4
İstanbul - İSTANBUL =
true
Örnekte öncelikle dört tane String nesnesi (değişkeni) oluşturduk. Görüldüğü
gibi ilk iki satırda equals()metodu yardımıyla String nesnelerini karşılaştırdık.
İlk satırda nesnelerimiz birbirine eşit olmadığı için metodumuz false değer
döndürdü.
Daha sonraki satırda ise büyük küçük harfe duyarlı olan equals() metodunu
kullandığımız için metodumuz geriye false değer döndürdü.
Daha sonraki satırda ise büyük küçük harfe duyarlı olan equals() metodunu
kullandığımız için metodumuz geriye false değer döndürdü.
Diğer satırda, karşılaştırdığımız iki String nesnesi zaten birbirine eşit olduğu
için metodumuz geriye truedeğer döndürdü. En son satırda ise harf duyarlılığı
olmayan euqalsIgnoreCase() metodunu kullandığımız için iki String nesnemiz
birbirine eşit oldu ve metot geriye true değer döndürdü.
Birinde İstanbul tamamen büyük yazıldı, diğerinde ise sadece ilk harfi büyük
yazıldı. Fakat bu metot ikisini de eşit olarak gördüğü için truedeğeri döndü.
Tabi bu dönen değerleri, ihtiyaca göre if veya switch yapılarının içerisine
koyarak başka işlemler de yaptırabiliriz.
COMPARETO VE COMPARETOIGNORECASE METODLARI İLE
BÜYÜKLÜK KONTROLÜ
Bazı durumlarda iki String nesnesinin birbirine eşit olup olmadığından çok,
hangisinin büyük olduğu veya hangisinin küçük olduğu önemlidir. Bu gibi
durumlarda compareTo() ve compareToIgnoreCase() metotlarını kullanırız.
Bu karşılaştırma metotları sıralama uygulamalarında büyük önem kazanır. Bir
dizgenin diğer dizgeden büyük veya küçük olması demek dizgelerin sözlük
sıralamalarıyla alakalıdır. Örneğin; bir isim sözcüğü oluşturduğumuzu
düşünelim ve sözlüğümüze iki isim ekleyelim. Bunlar, "Sezer" ve "Sezen"
olsun. "Sezen" ismi sözlükte "Sezer" isminden önce gelir, yani "Sezen" ismi
"Sezer" isminden daha küçüktür.
1.
compareTo() metodu; referans olarak verilen String nesnesini
kendisini çağıran String nesnesi ile karşılaştırır. Eğer geriye dönen
değer 0'dan büyükse; çağıran String nesnesi, referans olarak
gönderilen String nesnesinden büyüktür.
2.
Geriye dönen değer 0'dan küçükse (yani olumsuz ise) referans olarak
gönderilen değer, çağıran Stringnesnesinden büyüktür.
3.
Geriye dönen değer 0 ise iki String nesnesi
birbirine eşittir. compareTo() metodu, büyük - küçük harfe karşı
duyarlıdır, compareToIgnoreCase() metodu ise büyük - küçük harfe
duyarlı değildir.
Şimdi karşılaştırma metotlarını örnek üzerinden açıklayalım.
1
//StringOrnek2.java - 09.04.2014
2
3
public class StringOrnek2
4
{
5
public static void main(String[] args)
6
{
7
String isim1 = "Sezer";
8
String isim2 = "SEZER";
9
String isim3 = "Sezen";
10
String isim4 = "SEZEN";
11
12
System.out.print(isim1 + " ve " + isim3 + "
13
Karşılaştırması: ");
14
System.out.println(isim1.compareTo(isim3));
15
System.out.print(isim4 + " ve " + isim1 + "
16
Karşılaştırması: ");
17
System.out.println(isim4.compareToIgnoreCase(isim1));
18
System.out.print(isim1 + " ve " + isim2 + "
19
Karşılaştırması: ");
20
System.out.println(isim1.compareToIgnoreCase(isim2));
21
22
23
System.out.print(isim1 + " ve " + isim2 + "
Karşılaştırması: ");
System.out.println(isim1.compareTo(isim2));
}
}
Ekran çıktısı:
Sezer ve Sezen Karşılaştırması: 4
SEZEN ve Sezer Karşılaştırması:
1
-4
2
Sezer ve SEZER Karşılaştırması:
3
0
4
Sezer ve SEZER Karşılaştırması:
32
Örneğimizde karşılaştırma yaptığımız ilk satıra dikkat edelim.
1.
İlk satırda "Sezer" ve "Sezen" isimlerini karşılaştırdık ve metodumuz
geriye pozitif değer döndürdü. Bu metodu
çağıran String nesnesinin daha büyük olduğu anlamına gelmektedir.
2.
Daha sonraki satırda büyük - küçük harf duyarlılığı
olmayan compareTonIgnoreCase() metodunu "SEZEN" ve "Sezer"
isimlerinin karşılaştırmak için kullandık. Metodumuz, kendisini
çağıran Stringnesnesinin daha küçük olduğunu belirten negatif bir
değer gönderdi (-4).
3.
Bir sonraki satırda aynı metodu bu sefer "Sezer" ve "SEZER" isimleri
için kullandık. Harf duyarlılığı olmayan bu metot bize bu
iki String nesnesinin eşit olduğunu belirten 0 değerini gönderdi.
Çünkü bu metot, büyük küçük harfe duyarlı değildir.
Son satırda ise compareTo() metodunu yine "Sezer" ve "SEZER"
isimlerini karşılaştırmak için kullandık. Büyük - küçük harf duyarlılığı
olan bu metot, bize kendisini çağıran String nesnesinin daha
büyük olduğunu belirten pozitif bir değer döndürdü.
"Sezer" isminin "SEZER" isminden büyük olmasının sebebi; küçük
harflerin ASCII tablosunda büyük harflerden daha sonra gelmesidir.
REGIONMATCHES METODU İLE BELİRLİ BİR BÖLGENİN
KARŞILAŞTIRILMASI
Bu metot, String nesnesi içindeki belli bir bölgeyi, referans olarak
vereceğimiz String nesnesinin belli bir bölgesi ile karşılaştırmaya yarar.
Metodun kullanımına örnek vererek açıklayalım.
//StringOrnek3.java - 09.04.2014
1
2
public class StringOrnek3
3
{
4
public static void main(String[] args)
5
{
6
String d1 = "Ankara Türkiye'nin başkentidir.";
7
String d2 = "Türkiye";
8
boolean b;
9
10
b = d1.regionMatches(7, d2, 0, d2.length());
11
if(b == true)
12
{
13
System.out.println(d1 + " içerisinde aranan bölgede " + d2 + "
14
bulundu.");
15
}
16
else
17
{
18
System.out.println(d1 + " içerisinde aranan bölgede " + d2 + "
19
bulunamadı.");
20
}
21
}
22
}
23
Ekran çıktısı:
Ankara Türkiye'nin başkentidir. içerisinde aranan bölgede Türkiye
1
bulundu.
Örnekte d1 içerisinde belirlediğimiz indis değerinden başlayarak d2
String nesnesini karşılaştırdık.
1.
Metodumuzun ilk parametresi karşılaştırmaya hangi indis değerinden
başlanacağını ifade eder.
2.
İkinci parametre hangi String ile karşılaştırılacağını gösterir.
3.
Üçüncü parametre, karşılaştırmaya parametre olarak
verilen String nesnesinin hangi indis değerinden başlanacağını
gösterir.
4.
Dördüncü parametre ise, karşılaştırmanın kaç karakter devam
edeceğini gösterir.
STARTSWITH VE ENDSWITH METODLARI İLE BAŞLANGIÇ VE
BİTİŞ KONTROLÜ
Bu iki metot; String nesnesinin, referans olarak verilen String ile başlayıp
başlamadığını veya sonlanıp sonlanmadığını kontrol eder. startswith() metodu,
metodu çağıran String nesnesi, referans olarak verilenString ile
başlıyorsa true; başlamıyorsa false değer döndürür. Aynı
şekilde endsWith() metodu ise metodu çağıran String nesnesi, referans olarak
verilen String ile bitiyorsa geriye true; bitmiyorsa false değer döndürür.
Bu iki metot için de birer örnek yaparak konuyu daha iyi anlamaya çalışalım.
1
//StringOrnek4.java - 09.04.2014
2
3
public class StringOrnek4
4
{
5
public static void main(String[] args)
6
{
7
String dizge = "Elektroarge Elektronik Arastirma Gelistirme
8
Platformu";
9
boolean kontrol;
10
11
kontrol = dizge.startsWith("Elektroarge");
12
System.out.println(kontrol);
13
kontrol = dizge.startsWith("lektroarg");
14
System.out.println(kontrol);
15
kontrol = dizge.endsWith("Plat");
16
17
18
19
20
21
System.out.println(kontrol);
kontrol = dizge.endsWith("Platformu");
System.out.println(kontrol);
}
}
Ekran çıktısı:
1
true
2
false
3
false
4
true
Örnekte ilk iki kısımda String nesnemizin önce "Elektroarge" daha
sonra "lektroarg" ile başlayıp başlamadığını kontrol
ettik. startWith() metodumuzun ilk olarak String nesnemizin ilk karakteri ile
referans olarak verdiğimiz String'in ilk karakterini kontrol eder, iki karakter de
eşitse son karaktere kadar bu işlemi tekrarlar. Metodumuz iki durumda
da String nesnemizin referans olarak gönderdiğimiz String ile başlayıp
başlamadığını kontrol etti ve ilk durumda true; ikinci durumda ise false değer
döndürdü. endsWith() metodu,startsWith() metodunun diğer formu aşağıdaki
örnekte gibidir:
//StringOrnek5.java - 09.04.2014
1
2
public class StringOrnek5
3
{
4
public static void main(String[] args)
5
{
6
String dizge = "Elektroarge Elektronik Arastirma Gelistirme
7
Platformu";
8
boolean kontrol;
9
10
kontrol = dizge.startsWith("Elektroarge", 1);
11
System.out.println(kontrol);
12
kontrol = dizge.startsWith("lektroarg", 1);
13
System.out.println(kontrol);
14
}
15
}
16
17
Ekran çıktısı:
1
false
2
true
Örnekte görüldüğü gibi startsWith() metoduna hangi indis değerinden
karşılaştırmaya başlayacağımızı belirtebilir.
İkinci metot; true değerini döndürdü. Çünkü 1. indisten karşılaştırmaya yapınca
ikinci harf olan A'dan başlıyor.
Ders 100 - Karakter Metodları
String sınıfının metotlarıyla String nesneleri içerisindeki belli karakterleri
seçmek ve bunlara işlem yaptırmak mümkündür. String nesnelerine
başlarkan String nesnelerini karakter dizilerine benzetmiştik.String nesneleri,
karakter dizilerinde olduğu gibi karakterleri indis değerleriyle eşleyerek
kaydetmez. Ama bu dersimizde göreceğimiz bazı String metotları kendi işlerini
kolaylaştırmak amacıyla karakterleri indis değerleriyle eşleyerek işlem
yaparlar.
GETCHARS METODU İLE STRING İÇERİSİNDEKİ BİR BÖLÜMÜ
DİZİYE AKTARMA
Bu metot, String nesnesi içerisindeki belli sayıda karakteri bir diziye
aktarmamızı sağlar. Metodun genel kullanımı şu şekildedir:
getChars(int başlangıç, int bitiş, char kaynakDizi[], int
1
kaynakIndis);
Metodumuzun aldığı ilk parametre olan başlangıç parametresi String nesnesi
içerisinde kopyalanmaya başlanılacak indis değerini gösterir. Aynı
şekilde bitiş parametresi ise String nesnesi içerisindekopyalanmanın
sonlanacağı indis değerini gösterir. kaynakDizi[] ise String nesnesi
içerisinden alınan karakterlerin kopyalanacağı kaynak dizidir.
Son parametre olan kaynakIndis parametremiz ise kaynak dizimiz içerisine
kopyalanacak karakterlerinhangi indis değerinden sonra kopyalanması
gerektiğini bildirir.
Metodumuzu tam olarak anlayabilmek için şimdi bir örnek yapalım.
//StringOrnek.java - 11.04.2014
1
2
public class StringOrnek
3
{
4
public static void main(String[] args)
5
{
6
String dizge = "Bu derste String nesnesinin metotlarını
7
inceliyoruz";
8
char[] kaynakDizi = new char[6];
9
char[] kaynakDizi2 = new char[9];
10
char[] kaynakDizi3 = new char[11];
11
12
dizge.getChars(10, 16, kaynakDizi, 0);
13
System.out.println(kaynakDizi);
14
dizge.getChars(17, 26, kaynakDizi2, 0);
15
System.out.println(kaynakDizi2);
16
dizge.getChars(40, 51, kaynakDizi3, 0);
17
System.out.println(kaynakDizi3);
18
}
19
}
20
21
Ekran çıktısı:
1
String
2
nesnesini
3
inceliyoruz
Örneğimizde 3 adet kaynak dizi oluşturduk ve bu kaynak dizilere belli indis
değerlerinden başlayarak, belli indis değerlerinde sonlanacak karakterleri
kopyaladık.
CHARAT METODU İLE STRING İÇERİSİNDEKİ KARAKTERE
ULAŞMAK
Bir String nesnesi içerisinden belli bir noktadaki tek bir karakteri seçmek
istediğimizde bu metodu kullanırız.
Metodu bir örnekle daha iyi açıklayalım.
//StringOrnek2.java - 11.04.2014
1
2
public class StringOrnek2
3
{
4
public static void main(String[] args)
5
{
6
String alfabe =
7
"ABCÇDEFGHIİJKLMNOÖPRSŞTUÜVYZ";
8
System.out.print("Alfabenin 10. harfi: ");
9
System.out.println(alfabe.charAt(9));
10
System.out.print("Alfabenin 19. harfi: ");
11
System.out.println(alfabe.charAt(18));
12
}
13
}
14
15
Ekran çıktısı:
Alfabenin 10. harfi:
1
I
2
Alfabenin 19. harfi:
P
Yukarıdaki örnekte charAt() metodu yardımıyla içerisine alfabeyi
kaydettiğimiz String nesnesinin önce 10. karakterine daha sonra 19. karakterine
ulaşıp ekrana yazdırdık. Daha öncede açıkladığımız gibi metodumuz geriye tek
bir karakter döndürmektedir.
TOCHARARRAY METODU İLE STRING NESNEYİ KARAKTER
DİZİSİNE DÖNÜŞTÜRME
Bir String nesnesini karakter dizisine dönüştürmek
için toCharArray() metodunu kullanırız. Bu metot,String nesnesini karakter
dizisine çevirerek geriye dizi olarak döndürür.
Şimdi metodun daha iyi anlaşılması için metotla ilgili bir örnek yapalım.
1
//StringOrnek3.java - 11.04.2014
2
3
public class StringOrnek3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
public static void main(String[] args)
{
String dizge = "Karakter dizisine aktarılacak string";
int uzunluk = dizge.length();
// oluşturduğumuz string nesnesinin uzunluğunda bir karakter dizisi
oluşturduk.
char[] karakterDizisi = new char[uzunluk];
// string nesnemizi karakter dizisine çevirdik ve char tipinde diziye
attık.
karakterDizisi = dizge.toCharArray();
for(int a = 0 ; a <= dizge.length() - 1 ; a++)
System.out.print(karakterDizisi[a]);
}
}
Ekran çıktısı:
Karakter dizisine aktarılacak
1
string
Yukarıdaki örnekte oluşturduğumuz String nesnesinin içeriğini, karakter
dizisine çevirip, daha sonradan oluşturduğumuz karakter dizisine
atadık. for döngüsü yardımıyla karakter dizimiz içerisindeki tüm elemanları
yazdırdık. İsteseydik, bu dizinin tamamını değil de belirli bir kısmını
yazdırabilirdik. Bunu for döngüsündekidizge.length() - 1 koduyla ayarladık.
Gördüğünüz gibi bu metot, bir String'i diziye çeviriyor. String'in her harfi,
dizinin bir elemanı oluyor.
INDEXOF VE LASTINDEXOF METODLARI İLE STRING
İÇERİSİNDE KARAKTER ARAMA
String sınıfı, bize String içerisinde karakterleri arayabilmemiz için bu iki
metodu sunar. indexof(), Stringnesnesi içerisinde aranılan karakterin ilk
bulunduğu indis değerini verir. lastIndexOf() ise String nesnesi içerisinde
aranılan karakterin son bulunduğu indis değerini verir. Her iki metot için de
aranılan eleman bulunursa, indis değeri döndürülür; aranılan eleman
bulunamazsa geriye negatif değer döndürür.
Bu iki metodu anlayabilmek için bir örnek yapalım.
//StringOrnek4.java - 11.04.2014
1
2
public class StringOrnek4
3
{
4
public static void main(String[] args)
5
{
6
String dizge = "Bu arama yapabilmek için test
7
cümlesidir";
8
9
System.out.print("'a' karakteri için ilk indis: ");
10
System.out.println(dizge.indexOf("a"));
11
System.out.print("'a' karakteri için son indis: ");
12
System.out.println(dizge.lastIndexOf("a"));
13
System.out.print("'arama' kelimesi için ilk indis: ");
14
System.out.println(dizge.indexOf("arama"));
15
System.out.print("'deneme' kelimesi için son indis:
16
");
17
System.out.println(dizge.lastIndexOf("deneme"));
18
}
19
}
20
Ekran çıktısı:
'a' karakteri için ilk indis: 3
1
'a' karakteri için son indis: 12
2
'arama' kelimesi için ilk indis: 3
3
'deneme' kelimesi için son indis:
4
-1
Yukarıdaki örnekte görüldüğü gibi aranılan karakter veya String,
çağırılan String nesnesi içerisinde bulunursa indis değeri geriye döndürülüyor.
Aranılan değer bulunamazsa, negatif değer döndürülüyor. Aranılacak
parametreyi tırnak içerisinde veriyoruz. Görüldüğü gibi "denem" kelimesini
bulamadı ve negatifdeğer döndürdü.
Bu iki metodun istenilen bir noktadan sonra arama yapabilmek için aşırı
yüklenmiş formu bulunmaktadır. Aranılacak değer referans olarak verildikten
sonra, ikinci parametre olarak aramaya başlanılacak indis değeri giriliyor. Bu
kısma da kısa bir örnek vererek konuyu sonlandıralım.
//StringOrnek4.java - 11.04.2014
1
2
public class StringOrnek5
3
{
4
public static void main(String[] args)
5
{
6
String dizge = "Bu arama yapabilmek için test
7
cümlesidir";
8
9
System.out.print("'a' karakteri için ilk indis: ");
10
System.out.println(dizge.indexOf("a"));
11
System.out.print("'a' karakteri için son indis: ");
12
System.out.println(dizge.lastIndexOf("a", 8));
13
System.out.print("'i' karakteri için son indis: ");
14
System.out.println(dizge.lastIndexOf("i"));
15
System.out.print("'i' karakteri için ilk indis: ");
16
System.out.println(dizge.lastIndexOf("i", 37));
17
}
18
}
19
20
Ekran çıktısı:
'a' karakteri için ilk indis:
3
1
'a' karakteri için son indis:
2
7
3
'i' karakteri için son indis:
4
38
'i' karakteri için ilk indis:
36
Ders 101 - String Düzenleme Metodları
Java'da String nesnelerini düzenlemek için belirli metotlara ihtiyaç duyarız.
Düzenleme metotlarından bazıları ve bu metotların kullanımlarını bu bölümde
anlatacağız.
SUBSTRING METODU İLE STRING İÇERİSİNDEN BİR BÖLÜM
SEÇME
Bu metot String nesnesinin belli bir bölümünü seçmek için kullanılır. Metodun
genel kullanımı aşağıda gösterildiği gibidir.
String : substring (int ilkIndis, int
1
sonIndıs)
Metodun ilk parametresi olan ilkIndis parametresi, String nesnesi içerisinde
karakterlerin seçilmeye başlanacağı indis değerini gösterir. İkinci parametre
olan sonIndis parametresi ise, String nesnesi içerisinden karakter seçilmesinin
sonlanacağı indis değerini gösterir.
//StringOrnek.java - 09.04.2014
1
2
public class StringOrnek
3
{
4
public static void main(String[] args)
5
{
6
String dizge = "Bu örnek substring metodunun kullanımı için
7
yapıldı.";
8
String altDizge = "";
9
String altDizge2 = "";
10
11
// alt dizgelerimize string nesnesi içerisinden belirtilen karakterleri
12
atadık.
13
altDizge = dizge.substring(9, 18);
14
altDizge2 = dizge.substring(29, 38);
15
16
System.out.println(altDizge);
17
System.out.println(altDizge2);
18
}
19
}
20
Ekran çıktısı:
1
substring
2
kullanımı
Yukarıdaki örnekte oluşturduğumuz String nesnesi içerisinden belli
kısımları substring metodu yardımıyla seçtik ve diğer String nesnelerimize bu
değerleri atadık.
REPLACE METODU İLE STRING İÇERİSİNDEKİ KARAKTERİ
DEĞİŞTİRME
Bu metot, String nesnesi içerisinde belirtilen karakterleri başka karakter ile
değiştirmeye yarar.
Metodun genel kullanımı aşağıdaki gibidir:
String : replace(char orjinalKarakter,
1
chardegistirilenKarakter);
Metodumuzun aldığı ilk parametre
olan orjinalKarakter parametresi, String nesnesi içerisindeki değiştirilmek
istenen karakterdir.
İkinci parametre degistirilenKarakter parametresi ise String nesnesi
içerisindeki orjinalKarakter ile değiştirilecek karakteri belirtir.
Metodun kullanımına bir örnek yapalım:
1
//StringOrnek2.java - 09.04.2014
2
3
public class StringOrnek2
4
{
5
public static void main(String[] args)
6
{
7
String dizge = "Bu örnek substring metodunun kullanımı için
8
yapıldı.";
9
String dizge2 = "";
10
11
System.out.println("String nesnemizin orjinal hali: ");
12
System.out.println(dizge);
13
14
15
16
17
18
19
20
21
22
// string nesnemiz içerisindeki tüm 'e' karakterleri 'o' ile
değiştirildi.
dizge2 = dizge.replace('e', 'o');
// replace metodunu "dizge" adındaki değişken üzerinden
kullandık
System.out.println("String nesnemizin değiştirilmiş hali: ");
System.out.println(dizge2);
}
}
Ekran çıktısı:
String nesnemizin orjinal hali:
1
Bu örnek substring metodunun kullanımı için
2
yapıldı.
3
String nesnemizin değiştirilmiş hali:
4
Bu örnok substring motodunun kullanımı için
yapıldı.
Örnekte oluşturduğumuz String nesnesi içerisindeki tüm 'e' karakterlerini 'o'
karakteri ile değiştirmek içinreplace() metodunu kullandık. Metodu
kullanırken, hangi String üzerinde işlem yapacaksak, replacemetodunu o
String ile kullanmalıyız.
TRIM METODU İLE STRING İFADENİN YANINDAKİ BOŞLUKLARI
SİLME
Bu metot, String nesnemizin sağındaki ve solundaki boşlukları silerek
düzenlenmiş bir kopyasını döndürür. Metodun kullanımına örnek yaparak
metodu daha iyi açıklayalım.
1
//StringOrnek3.java - 09.04.2014
2
3
public class StringOrnek3
4
{
5
public static void main(String[] args)
6
{
7
String dizge = " Bu cümlenin başındaki ve sonundaki
8
boşluklar
9
T
rim metoduyla silinecektir. ";
10
11
12
13
14
15
16
17
18
System.out.println("String nesnesinin orjinal hali: ");
System.out.println(dizge);
System.out.println("String nesnemizin düzenlenmiş hali:
");
System.out.println(dizge.trim());
}
}
Ekran çıktısı:
String nesnesinin orjinal hali:
1
Bu cümlenin başındaki ve sonundaki boşluklar trim metoduyla
2
silinecektir.
3
String nesnemizin düzenlenmiş hali:
4
Bu cümlenin başındaki ve sonundaki boşluklar trim metoduyla
silinecektir.
Örneğimizde önce başında ve sonunda üç karakterlik boşluk bulunan
bir String nesnesi oluşturduk. Daha sonra ekran çıktısından da olduğu gibi bu
nesnemizin başındaki ve sonundaki boşlukları trim() metodu yardımıyla
sildik.
TOUPPERCASE VE TOLOWERCASE METODLARI İLE HARF
KİPİNİ DEĞİŞTİRME
Bu iki metot, String nesnesi içerisindeki harflerin kipini değiştirmek için
kullanılırlar. toUppercase()metodu, String nesnemiz içerisindeki
harfleri büyük harfler ile değiştirir. toLowerCase() metodu
ise Stringnesnemiz içerisindeki harfleri küçük harfleri ile değiştirmek için
kullanılır.
1
//StringOrnek4.java - 09.04.2014
2
3
public class StringOrnek4
4
{
5
public static void main(String[] args)
6
{
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
String dizge = "Bu ÖrNeK HaRf KiPi DeğişiMi MeToTlaRı içiN
Yapıldı.";
String kucuk = "";
String buyuk = "";
System.out.println("String nesnesinin orjinal hali: ");
System.out.println(dizge);
buyuk = dizge.toUpperCase();
System.out.println("Büyük harf kipi ile String nesnesi: ");
System.out.println(buyuk);
kucuk = dizge.toLowerCase();
System.out.println("Küçük harf kipi ile String nesnesi: ");
System.out.println(kucuk);
}
}
Ekran çıktısı:
String nesnesinin orjinal hali:
1
Bu ÖrNeK HaRf KiPi DeğişiMi MeToTlaRı içiN Yapıldı.
2
Büyük harf kipi ile String nesnesi:
3
BU ÖRNEK HARF KİPİ DEĞİŞİMİ METOTLARI İÇİN
4
YAPILDI.
5
Küçük harf kipi ile String nesnesi:
6
bu örnek harf kipi değişimi metotları için yapıldı.
VALUEOF METODU İLE VERİ TİPLERİNİ STRING VERİ TİPİNE
ÇEVİRME
Bu metot, Java'da veri tiplerini String tipine çevirmek için kullanılır. Metot
aldığı parametreyi, geriyeString tipinde gönderir. Metodun hangi tipte veriler
üzerinde kullanıldığını görmek için bir örnek yapalım.
1
//StringOrnek5.java - 11.04.2014
2
3
public class StringOrnek5
4
{
5
public static void main(String[] args)
6
{
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int i = 10;
float f = 11.f;
double d = 12.d;
long l = 100000000;
char c = 'c';
boolean b = false;
Object o = new String("Deneme");
String s = "";
// değişik tipteki verileri string tipine
çeviriyoruz.
s = String.valueOf(i);
s = s + "-" + String.valueOf(f);
s = s + "-" + String.valueOf(d);
s = s + "-" + String.valueOf(l);
s = s + "-" + String.valueOf(c);
s = s + "-" + String.valueOf(b);
s = s + "-" + String.valueOf(o);
System.out.println(s);
}
}
Ekran çıktısı:
10-11.0-12.0-100000000-c-false1
Deneme
Yukardaki örnekte değişik tipte verileri String tipine çevirmek
için valueOf() metodunu kullandık. Daha sonra String tipine çevirdiğimiz bu
verileri bir String nesnesi içerisinde birleştirdik. Alt satırlara doğru indikçe çığ
tipi toplanarak giden bir s değişkenimiz var. Bu değişken, son satırda bütün
metot sonuçlarını kendi üzerinde birleştirmiştir.
Ders 102 - StringTokenizer ve StringBuffer Sınıfları
Bu dersimizde String sınıfının dışında kullanılan ve belli başlı işlemleri yapan
iki sınıfımızı inceleyeceğiz.
Bunlar StringTokenizer ve StringBuffer sınıflarıdır.
STRINGTOKENIZER SINIFINI KULLANARAK METNİ
PARÇALAMA
Bir String ifademizi parçalamak isteyebiliriz. Mesela; uzun bir cümlemiz var
ve biz bu cümle içerisinden kelimeleri almak istiyoruz. Bunun
için StringTokenizer sınıfını kullanmamız gerekir.
StringTokenizer sınıfı, bir String ifadeyi belirli bir parametreye göre parçalar.
Eğer uzun bir cümlemiz varsa, biz bu cümlede parametre
olarak boşluk verirsek, ifademiz her boşlukta parçalara ayrılır.
Ayrılan her parçaya token denir. Parçalama işlemini yapacak olan
parametreye delimeter denir.
Şimdi bir örnek yapalım ve konumuza örnek üzerinden devam edelim.
//Tokenizer.java - 11.04.2014
1
2
import java.util.StringTokenizer;
3
public class Tokenizer
4
{
5
public static void main(String[] args)
6
{
7
String cumle = "Yenilirsen Değil Vazgeçersen
8
Kaybedersin";
9
StringTokenizer s1 = new StringTokenizer(cumle);
10
while(s1.hasMoreTokens())
11
// parçalanacak ifade varsa; true değeri döner ve döngü
12
işlenir
13
{
14
System.out.println(s1.nextToken()); // parçayı yazdır
15
}
16
}
17
}
18
Ekran çıktısı:
1
Yenilirsen
2
Değil
3
Vazgeçersen
4
Kaybedersin
1.
Örneğimizde ilk olarak import işlemi yaptık.
Çünkü StringTokenizer sınıfını kullanabilmek için bu
sınıfıimport etmemiz gerekiyor.
2.
Daha sonra main içerisinde bir cümle belirledik.
3.
Sonra da StringTokenizer sınıfından bir nesne oluşturduk. Parametre
olarak da StringTokenizersınıfının yapıcısına cumle değişkenini
verdik. Yani bu değişken üzerinde parçalama işlemi yapılacak.
4.
while döngümüzde bu s1 nesnesi
üzerinden hasMoreTokens() metodunu çağırdık. Bu metot,
parçalanacak bir ifade kalıp kalmadığını kontrol eder.
5.
Eğer hala parçalanacak bir ifade varsa, döngü döner ve döngü
içerisinde de s1 üzerinden nextToken()metodu çağırılır. Bu metot da
her seferinde parçalanan bir ifadeyi döndürür.
Bu örneğimizde boşluklara göre parçalama yaptık.
Normalde StringTokenizer sınıfının yapıcısına cümlenin yanında hangi
karaktere göre parçalama yapacağımızı da verirdik. Fakat bu örnekte
vermedik. Çünkü boşluk ifadesi default parametredir. Biz boşluk değil de
mesela - karakterine göre parçalama yapmak istersek, cümlenin yanına bu
parametreyi de ekleriz.
Şimdi bu anlattığımıza örnek verelim.
1
//Tokenizer2.java - 11.04.2014
2
3
import java.util.StringTokenizer;
4
public class Tokenizer2
5
{
6
public static void main(String[] args)
7
{
8
String cumle = "ElektroArge-Elektronik-Arastirma-Gelistirme9
Platformu";
10
String bolucu = "-";
11
StringTokenizer s1 = new StringTokenizer(cumle, bolucu);
12
while(s1.hasMoreTokens())
13
// parçalanacak ifade varsa; true değeri döner ve döngü işlenir
14
{
System.out.println(s1.nextToken()); // parçayı yazdır
15
16
17
18
19
}
}
}
Ekran çıktısı:
1
ElektroArge
2
Elektronik
3
Arastirma
4
Gelistirme
5
Platformu
Yukarıdaki örneğimizde bolucu adında bir değişken tanımladık. Yani
"cümlemizde bu değişkenin değerini gördüğün her yerde ayırma yap". Bu sefer
cümlemizde aralarda - ifadesi koyduk ki bunu gördüğü her
yerdeayırma yapsın, yani token'lara bölsün.
Istisnalar:
!
StringTokenizer sınıfının yaptığını, split() metodunun yaptığı işe
benzetebiliriz.
Başka bir örnek verelim.
1 //Tokenizer3.java - 11.04.2014
2
3 import java.util.StringTokenizer;
4 public class Tokenizer3
5 {
6
public static void main(String[] args)
7
{
8
String cumle = "ElektroArge,-Elektronik-,Arastirma-Gelistirme9 ;Platformu";
10
String bolucu = ",;";
11
StringTokenizer s1 = new StringTokenizer(cumle, bolucu);
12
while(s1.hasMoreTokens())
13
{
14
System.out.println(s1.nextToken());
15
}
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
}
33 }
34
System.out.println("*********************");
String bolucu2 = "-;";
StringTokenizer s2 = new StringTokenizer(cumle, bolucu2);
while(s2.hasMoreTokens())
{
System.out.println(s2.nextToken());
}
System.out.println("*********************");
String bolucu3 = "a";
StringTokenizer s3 = new StringTokenizer(cumle, bolucu3);
while(s3.hasMoreTokens())
{
System.out.println(s3.nextToken());
}
Ekran çıktısı:
1
ElektroArge
2
-Elektronik3
Arastirma-Gelistirme4
Platformu
5
*********************
6
ElektroArge,
7
Elektronik
8
,Arastirma
9
Gelistirme
10
Platformu
11
*********************
12
ElektroArge,-Elektronik-,Ar
13
stirm
14
-Gelistirme-;Pl
15
tformu
Yukarıdaki örneğimizde 3 farklı bölme parametresi kullandık ve her biri için
çıkan sonucu gösterdik. Örnekte bir istisna vardır, o da şu:
İlk örnekte kesme işlemini yapan bolucu parametremiz ,; ifadesinden oluşuyor.
Cümlemizde de ilk olarakvirgül(,) ifadesi aranıyor. Eğer bu ifade varsa kesme
yapılıyor. Eğer yoksa bu sefer noktalı virgül(;) ile arama yapılıyor.
Peki, bu istisna neden var? Çünkü bir cümlede birçok noktalama işareti varsa,
bu noktalama işaretleri parametremize uygun bir şekilde verilir ve tüm
kelimeler elde edilir. Hemen bir örnek daha yapalım.
//Tokenizer4.java - 11.04.2014
1
2
import java.util.StringTokenizer;
3
public class Tokenizer4
4
{
5
public static void main(String[] args)
6
{
7
String cumle = "(3*5)+(4/10)";
8
String bolucu="((*+/";
9
StringTokenizer s1 = new StringTokenizer(cumle,
10
bolucu);
11
while(s1.hasMoreTokens())
12
{
13
System.out.println(s1.nextToken());
14
}
15
System.out.println("*************");
16
String bolucu2 = "(*)+/";
17
StringTokenizer s2 = new StringTokenizer(cumle,
18
bolucu2);
19
while(s2.hasMoreTokens())
20
{
21
System.out.println(s2.nextToken());
22
}
23
}
24
}
25
Ekran çıktısı:
1
3
2
5)
3
4
4
10)
5
*************
6
3
7
5
8
4
9
10
Yukarıdaki örnekte bir matematiksel işlem var ve biz bu işlemdeki sayıları elde
etmeye çalışıyoruz. Bunun için 2 tane bölücü ifade kullandık. Örnekte yalnızca
bu iki kesme parametresi farklı. Bunu da şunun için yaptık. Cümlemizde
hangi sıradaysa, biz de bölücümüzde o sırada yapmak zorundayız. Alttaki
bölücüde uygun sıraya göre yazdık ve tüm sayıları saf haliyle elde ettik. İlk
bölücüde (delimeter) sırasını farklı yaptık ve yanlış sonuç aldık. Cümledeki
noktalama işaretleri de bu şekilde sıraya göre yapılmalıdır.
StringTokenizer kullanırken token yerine element kullanılarak da aynı işi
yapabiliriz. Bunun için sadece metotlarımızda değişiklik yaparız. Örnek
üzerinde gösterelim.
//Tokenizer5.java - 12.04.2014
1
2
import java.util.StringTokenizer;
3
public class Tokenizer5
4
{
5
public static void main(String[] args)
6
{
7
String cumle = "C:\\Windows\\System32";
8
String bolucu = ":\\";
9
StringTokenizer s1 = new StringTokenizer(cumle,
10
bolucu);
11
while(s1.hasMoreElements())
12
{
13
System.out.println((String)s1.nextElement()); //
14
cast
15
}
16
}
17
}
18
Ekran çıktısı:
1
C
2
Windows
3
System32
Bu örneğimizde yalnızca hasMoreElements() ve nextElement() metotlarını
değiştirdik. String tipinde cast etmemizin sebebi ise; üretilen sonucu String
tipinde almamız gerektiğidir.
Peki, cümlemizi pars ettik yani parçalara ayırdık ve ayrılan bu parçaları yani
token'ların sayısını elde etmek istersek, ne yapmamız gerekir? Tabi klasik
olarak sayaç ile yapabiliriz. Fakat bunun için hazırlanmış bir metodumuz var
onu kullanalım ve örnek üzerinde gösterelim.
//Tokenizer6.java - 12.04.2014
1
2
import java.util.StringTokenizer;
3
public class Tokenizer6
4
{
5
public static void main(String[] args)
6
{
7
String cumle = "Java dersleri için en önemli kaynak
8
elektroarge.com";
9
StringTokenizer s1 = new StringTokenizer(cumle);
10
11
System.out.println(s1.countTokens());
12
while(s1.hasMoreTokens())
13
{
14
System.out.println((String)s1.nextToken());
15
}
16
}
17
}
18
19
Ekran çıktısı:
1
7
2
Java
3
dersleri
4
için
5
en
6
önemli
7
kaynak
8
elektroarge.com
Örneğimizde boşluk parametresine göre parsing işlemi yaptık. Elde
edilen token sayısını isecountTokens() metodu ile bulduk. Fakat bu
metodu, while döngüsünden önce yazdık. Eğer sonra yazarsak, hep 0 sayısını
elde edeceğiz.
STRINGBUFFER SINIFI İLE BAZI METİN İŞLEMLERİ
Java'da String veri tipi, diğerlerinden farklıdır. String bir veri üzerinde birçok
işlem yapılabilir ve bunlarString sınıfının metotları ile yapılır.
Bir String tipindeki veriye ekleme çıkarma gibi işlemleri kitabımızın başında
anlatmıştık. + operatörü kullanılarak, karakter katarları üzerinde ekleme işlemi
yapılabiliyordu. Şimdi basit bir ekleme işlemi yapalım.
1
String ad = "Okan";
2
ad += " Bilke ";
3
System.out.println(ad);
Bu işlem sonucunda bize "Okan Bilke" ifadesi dönecektir. Fakat burada yapılan
her ekleme işleminde aslında arkaplanda StringBuffer sınıfı kullanılır. Biz
ekleme işlemi yaptığımızda aslında StringBuffer sınıfının ekleme görevi gören
metotlarıyla bu işlem yapılır. Bu ekleme işlemini yapan
metot, append() metodudur.
Şimdi yukarıdaki örneği StringBuffer sınıfını kullanarak yapalım.
1
//StringBufferSinifi.java - 12.04.2014
2
3
public class StringBufferSinifi
4
{
5
public static void main(String[] args)
6
{
7
StringBuffer s = new StringBuffer("Okan");
8
s.append("Bilke");
9
System.out.println(s);
10
}
11
}
12
13
Ekran çıktısı:
1
OkanBilke
StringBuffer sınıfından bir nesne oluşturduk ve ilk değer olarak
bir String ifade girdik. Daha sonra oluşturulan nesne
üzerinden append() metodunu çağırdık ve s nesnemizin sonuna eklenecek
ifadeyi girdik. Daha sonra bu s nesnesini ekrana yazdırdık. Aslında ilk
örneğimizde bu işlemler oluştu. Biz sadece sonucu gördük. Fakat bu işlemler
arkaplanda StringBuffer sınıfı ile yapıldı.
String ifadelere yalnızca String değil, başka tiplerde de veri ekleme
yapabiliyorduk. Yine aynı şekildeStringBuffer sınıfını kullanarak, bu sefer
başka tiplerde de eklemeler yapalım. Ayrıca her ekleme işlemini tek bir satırda
yapalım.
1
//StringBufferSinifi2.java - 12.04.2014
2
3
public class StringBufferSinifi2
4
{
5
public static void main(String[] args)
6
{
7
StringBuffer s = new StringBuffer("x");
8
s.append("--").append(55).append(5.1);
9
System.out.println(s);
10
}
11
}
12
13
Ekran çıktısı:
1
x--555.1
Bu örneğimizde s nesnesi oluşturduk ve ilk değer olarak x verdik. Daha sonra
bu nesne üzerinden 3 defa arka arkaya append() metodunu çağırdık ve bu
metot içerisine istediğimiz tipte verileri ekledik.
Çünküappend() metodu, Object sınıfından aşırı yüklenmiştir ve tüm tipleri
alabilir. Son olarak da bu nesnemizi ekrana yazdırdık. Bu nesne String tipinde
olduğu için doğrudan ekrana yazdırabiliyoruz.
StringBuffer sınıfının append() metodunun işlevini gördük. Bundan başka
metotlar da vardır. Mesela; indisleri verilen yere bir ifade ekleyebiliriz.
Bunu replace() metodu ile yaparız. Ayrıca indisi verilen yere istenilen değeri
yerleştirebiliriz. Örnek verirsek;
1
//StringBufferSinifi3.java - 12.04.2014
2
3
public class StringBufferSinifi3
4
{
5
public static void main(String[] args)
6
{
7
8
9
10
11
12
13
14
15
16
17
StringBuffer s = new
StringBuffer("Okan");
s.append("Bilke"); // ElektroArGe elde
edilir.
s.replace(0, 4, "Onur"); // yer değiştirme
System.out.println(s);
s.insert(4, "Okan"); // ekleme
System.out.println(s);
}
}
Ekran çıktısı:
1 OnurBilke
2 OnurOkanBilke
Yukarıdaki örnekte ilk olarak ekleme yapıp OkanBilke metinin elde ettik.
Daha sonra replace()metodunu kullanarak 0 ile 4. indisler arasını "Onur"
metniyle değiştirdik ve sonucu ekrana yazdırdık. Son olarak da bu yeni metin
üzerinden insert() metodunu kullanarak 4. indisten itibaren "Okan" metnini
ekledik ve sonucu yazdırdık.
Son olarak StringBuffer sınıfından 2 metot daha inceleyelim. Bunlar silme
işlemi yapan delete() ve metni tersine çeviren reverse() metotlarıdır.
1
//StringBufferSinifi4.java - 12.04.2014
2
3
public class StringBufferSinifi4
4
{
5
public static void main(String[] args)
6
{
7
StringBuffer s = new
8
StringBuffer("Okan");
9
s.append("Bilke");
10
s.delete(0, 4); // silme işlemi yapar
11
System.out.println(s);
12
13
s.reverse(); // metni tersine döndürür
14
System.out.println(s);
15
}
16
}
17
Ekran çıktısı:
1
Bilke
2
ekliB
Yukarıdaki örneğimizde de delete() ile 0. ve 4. indisler arasındaki bölgeyi
sildik. Daha sonra kalan metnin, yani s nesnesinin reverse() ile tersini aldık.
JAVA DİLİYLE
PROGRAMLAMA
Part II
Ders 103 - Exceptions (İstisnalar)
İstisnalar veya orjinal isimleriyle Exception'lar, kod blokları arasında oluşan
anormal durumlardır. En basit olarak bir örnek vermek gerekirse; bir sayıyı
sıfıra bölme bir istisnai durumdur veya bir diziye boyutundan fazla eleman
atamak, sayı girilmesi istendiği durumda bir String girmek birer istisnai
durumdur. Bu gibi durumlarda derleyici hata verecektir. Exception'lar hata tipi,
hata oluştuğunda uygulamanın durumu ve hata hakkında açıklayıcı bir takım
bilgiler içerir. Exception'lar sayesinde hata yakalamak ve sorunu çözmek daha
da kolaylaşır.
Yukarıda söylediklerimizin dışında, açık bir dosya üzerinde yazma işlemi
yapıldığında, dosyanın gösterilen adreste olmaması gibi durumlarda da hata ile
karşılaşılacaktır. Bunlar da bir diğer istisnalardır.
Bir öğrenci not sistemi uygulaması yaptınız diyelim. Java'nın tüm
üstünlüklerini kullandınız, fakat öğrenci not yerine yanlışlıkla adını girerse ne
olacak? Eğer bu girilen veriyi kontrol etmezseniz çalışırken birden bire hata
oluşacak ve programınız çalışmayacaktır. Sıradaki derslerimiz, bu şeklide
programınızda oluşabilecek hataları nasıl kontrol edeceğinizi anlatmaktadır.
Programınızda oluşabilecek bu tür hatalara sebebiyer verecek şeyler
birer istisnadır. Peki, bu şekilde istisnalar ile karşılaşırsak ne yapmamız
gerekir? Bundan sonraki derslerimizde bunun çözümüne değinilecektir.
Ders 104 - Hata Yakalama (Try - Catch Blokları)
Önceki dersimizde anlattığımız istisnalardan 0'a bölme konusuna bir örnek
verelim. Dersimizi örnek üzerinden detaylı bir şekilde anlatalım.
1
//Trycatch.java - 12.04.2014
2
3
public class Trycatch
4
{
5
public static void main(String[]
6
args)
7
{
8
int a = 10;
9
10
11
12
13
14
15
16
int b = 0;
int c;
c = a / b;
System.out.println("Sonuc: " +
c);
}
}
Ekran çıktısı:
Exception in thread "main" java.lang.ArithmeticException: /
1
by zero
2
at Trycatch.main(Trycatch.java:11)
Çıktımızda da görüldüğü gibi programımız çalışma zamanında bir hata
verecektir. Derleyicinin vereceği
hata, java.lang.ArithmeticException hatasıdır. Java, hatalar konusunda çok
sıkı davranır ve hataları anında kullanıcıya gösterir.
Geliştireceğiniz kodlarda hata her zaman bu kadar basit ve anlaşılır
olmayacaktır. Hatayı anlayıp ayıklayabilmek için try-catch bloğu
kullanmalıyız.
Bu try-catch bloğu sayesinde, hata ile karşılaştığımızda ne yapmamız gerekir
veya hata olsa da olmasa da programımızda neler yaptırmak istiyoruz, bunları
programımıza anlatabiliriz.
Temel try - catch bloğu kullanımı aşağıdaki gibidir:
try
1
{
2
// istisnai durum kontrolü yapacak kod
3
}
4
catch (Exception_türü e)
5
{
6
// (Exception_türü) hatası durumunda
7
çalışacak kod
8
}
9
finally
10
{
11
// hata alınsa da alınmasa da çalışacak kod
12
}
Hata oluşma ihtimali olan kodumuzu try bloğu içerisine alırız. try bloğu
çalıştığında eğer bir hata olursacatch bloğuna girilir. Hangi türde bir hata
olduysa bu hata ekrana yazdırılır. Burada
tanımlananException_türü tipindeki e nesnesi bize hata hakkında bilgiler verir.
Yukarıdaki bölme örneğini şimdi de try - catch bloğu yardımıyla yapalım.
//Trycatch2.java - 12.04.2014
1
2
public class Trycatch2
3
{
4
public static void main(String[] args)
5
{
6
int a = 10;
7
int b = 0;
8
int c;
9
try
10
{
11
c = a / b;
12
System.out.println("Sonuc: " + c);
13
}
14
catch (ArithmeticException ae)
15
{
16
System.out.println("Bir hata ile karşılaşıldı: " +
17
ae.toString());
18
}
19
}
20
}
21
22
Ekran çıktısı:
Bir hata ile karşılaşıldı: java.lang.ArithmeticException: /
1
by zero
Yukarıdaki örnekte görüldüğü gibi derleyici değişkenlere atamaları yaptıktan
sonra try bloğunu işleme alıyor. Biz diyoruz ki "Bölme işlemine bak, burada
bir hata olabilir." O yüzden hata olabilecek yerleri try içerisine aldık. Bu
kodda bir hatamız var. Bu bölme işleminde, sıfıra bölme hatasıyla karşılaşıldığı
anda catch bloğuna geçip hata mesajımızı gösteriyor. Normalde derleyici hata
ile karşılaştığında programı durdururdu ve bir hata mesajı verirdi. Biz
bu catch içerisinde diyoruz ki programı durdurma, kullanıcıya hatayı göster.
Hata mesajımızın ilk bölümü hatanın tipi ile ilgilidir. İkinci bölüm ise hatanın
neden kaynaklandığı ile ilgilidir. Burada ilk bölüm olan hatanın
tipi ArithmeticException'dır. Hatanın neden kaynaklandığı ise, ae nesnesinin
içerisinde saklıdır. Biz ae nesnesini ae.toString() ile ekrana yazdırarak hatanın
sebebini öğreniriz.
Istisnalar:
Eğer catch bloğunda tanımladığımız hata tipi ile karşılaştığınız hata
! tipi uyuşmuyorsa, muhtemelen hatayı yakalayamayacaksınız. Bu gibi
durumlarda catch bloğunda genel hata tipi (Exception) tanımlamak veya
birden fazla catch bloğu bulundurmak hatayı yakalamanızı
kolaylaştıracaktır.
Notumuzda şunu demek istiyoruz: Yukarıda ilk bölüm hatanın
tipidir demiştik. Bu hatanın tipi kısmınaException yazarak bunu önleyebiliriz.
Bu, bütün hata tiplerini kapsar, genel hata tipidir.
Şimdi hata yakalamaya başka bir örnek verelim.
//Trycatch3.java - 12.04.2014
1
2
public class Trycatch3
3
{
4
public static void main(String[]
5
args)
6
{
7
int dizi[] = new int[]{1, 3, 8, 23,
8
44};
9
System.out.println(dizi[6]);
10
}
11
}
12
Ekran çıktısı:
Exception in thread "main"
1
java.lang.ArrayIndexOutOfBoundsException: 6
2
at Trycatch3.main(Trycatch3.java:8)
Bu örnekte dizimizin 6. indisli elemanını ekrana yazdırmak istiyoruz. Fakat
dizimizde 6. indis bulunmamaktadır. Dolayısıyla olmayan bir elemana erişmek
hata verecektir. Yukarıdaki çıktıda hatamızın sebebi yazmaktadır.
java.lang.ArrayIndexOutOfBoundsException hatamızın sebebidir. Yani
dizideki indeksin dışında bir elemana erişmeye çalıştık. Peki, bunu try catch blokları ile nasıl kontrol altına alacağız?
//Trycatch4.java - 12.04.2014
1
2
public class Trycatch4
3
{
4
public static void main(String[] args)
5
{
6
int dizi[] = new int[]{1, 3, 8, 23, 44};
7
try
8
{
9
System.out.println("Try bloğu
10
içerisindeyiz");
11
System.out.println(dizi[6]);
12
}
13
catch (ArrayIndexOutOfBoundsException
14
a)
15
{
16
System.out.println(a.toString());
17
}
18
}
19
}
20
Ekran çıktısı:
Try bloğu içerisindeyiz
1
java.lang.ArrayIndexOutOfBoundsException:
2
6
Hata olabilecek bir ifade olan dizi[6] ifadesi try içerisine yazıldı. Bir hata
oluştuğunda ise; hatanın sebebicatch içerisine yazıldı. Eğer try catch kullanmasaydık, program çalışmayacaktı, fakat şimdi programımız
çalıştı. Hatta çalıştığını görmek için "Try bloğu içerisindeyiz" yazısını da
ekledik ve çıktıda da gördük. Eğer try - catch kullanmasaydık bu mesajı dahi
göremeyecektik, çünkü program hatay bulunca çalışmayacaktı.
catch bloğu içerisinde hatamızın sebebini yazdırmak yerine, herhangi
bir String ifadesi de yazdırabiliriz. Hemen bir örnek verelim.
//Trycatch5.java - 12.04.2014
1
2
public class Trycatch5
3
{
4
public static void main(String[] args)
5
{
6
int dizi[] = new int[]{1, 3, 8, 23, 44};
7
try
8
{
9
System.out.println("Try bloğu
10
içerisindeyiz");
11
System.out.println(dizi[6]);
12
}
13
catch (ArrayIndexOutOfBoundsException
14
a)
15
{
16
System.out.println("Hata oluştu");
17
}
18
}
19
}
20
Ekran çıktısı:
Try bloğu
1
içerisindeyiz
2
Hata oluştu
Bu örnekte a nesnesi üzerinden hatanın sebebini yazdırmak yerine kendi
belirlediğimiz bir ifadeyi yazdırdık.
try - catch ile hata yakalamaya bir örnek daha verelim. Önce hatamıza sebep
olacak bir örnek verelim. Daha sonrada try - catch ile programımızı kontrol
edelim.
1
//Trycatch6.java - 12.04.2014
2
3
import java.util.Scanner;
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Trycatch6
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.println("Vize notunuzu
girin:");
int vize = s.nextInt();
System.out.println("Vize notunuz: " +
vize);
}
}
Ekran çıktısı:
Vize notunuzu girin:
1
50Okan
2
Exception in thread "main"
3
java.util.InputMismatchException
4
at java.util.Scanner.throwFor(Unknown Source)
5
at java.util.Scanner.next(Unknown Source)
6
at java.util.Scanner.nextInt(Unknown Source)
7
at java.util.Scanner.nextInt(Unknown Source)
8
at Trycatch6.main(Trycatch6.java:11)
Biz bu örnekte Scanner sınıfını kullanarak kullanıcıdan vize notunu girmesini
istedik. Bu girilen değer inttipinde bir değişkene atandı. Fakat kullanıcı
yanlışlıkla bir String ifade girerse bu hataya sebep olacaktır ve programımız
çalışmayacaktır. Şimdi try - catch ile bu hatamızı kontrol altına alalım ve
programımız hemen durmasın çalışmaya devam etsin.
1
//Trycatch7.java - 12.04.2014
2
3
import java.util.Scanner;
4
5
public class Trycatch7
6
{
7
public static void main(String[] args)
8
{
9
int vize;
10
Scanner s = new Scanner(System.in);
11
12
System.out.println("Vize notunuzu
13 girin:");
14
try
15
{
16
vize = s.nextInt();
17
}
18
catch (Exception e)
19
{
20
System.out.println("Bir hata oluştu:");
21
System.out.println(e.toString());
22
System.out.println("Vize notu
23 alınamadı");
24
}
25
}
}
Ekran çıktısı:
1 Vize notunuzu girin:
2 54asd
3 Bir hata oluştu:
4 java.util.InputMismatchException
5 Vize notu alınamadı
Kullanıcıdan değer aldığımız metodu try içerisine yazdık. Hata ile
karşılaşıldığında e nesnesi üzerinden hatamızın sebebi yazdırıldı. Biz bu sebebi
yazdırmanın yanında kendimiz de bir mesaj yazdırdık. try - catchkullanarak,
programımızın tabiri caizse patlamasını engelledik. Hata oluşsa da program
çalışır, birden durmaz.
Diyelim ki kpss puanı hesaplayan bir programımız var. Bu programda eğer biz
kullanıcıdan doğru veyanlış sayısını alırken try içerisinde kontrol ettirmezsek
programımız donar ve hata verir. Eğer bu kontrolü yaparsak hata yakalandığı
anda kullanıcıya şöyle bir mesaj gösterebiliriz (Lütfen bir sayı girin). Böyle bir
mesaj verdiğimizde kullanıcı istediği kadar String bir veri girsin, bu mesaj hep
görüntülenecektir ve program çalışmayacaktır.
Try - catch ifadesini bir metod içerisinde de kullanabiliriz.
1 //Trycatch8.java - 12.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Trycatch8
{
public static void main(String[] args)
{
Trycatch8 nesne = new Trycatch8();
nesne.hataYakala();
}
public void hataYakala()
{
String dizi[] = new String[]{"Okan", "Bilke"};
try
{
System.out.println("Dizinin 1.elamanı: " + dizi[0]);
System.out.println("Dizinin 2.elemanı: " + dizi[1]);
System.out.println("Dizinin 3.elemanı: " + dizi[2]);
}
catch (Exception e)
{
System.out.println("Dizi yazdırılırken hata oluştu, oluşan
hata: ");
System.out.println(e.toString());
}
}
}
Ekran çıktısı:
Dizinin 1.elamanı: Okan
1
Dizinin 2.elemanı: Bilke
2
Dizi yazdırılırken hata oluştu, oluşan hata:
3
java.lang.ArrayIndexOutOfBoundsException:
4
2
Hata kontrolünü, bir metot içerisinde yaptık. Dizinin elemanlarını yazdırırken
ilk 2 elemanı yazdı, fakat son ifadede hata verdi. Çünkü 2. indisimiz
bulunmamaktadır. Hatamız oluştuğunda da e nesnesi üzerinden hatamızı
yazdırdık. Eğer try - catch kontrolü yapmasaydık, ilk iki elemanı da
yazdırmayacaktı doğrudan program hata verecekti.
Istisnalar:
!
JavaSE-7 ile gelen yenilikle beraber catch bloğu içerisinde,
oluşabilecek hatalar tek satırda tanımlanabiliyor. Bunu ileriki
derslerimizde detaylı olarak anlayacağız.
Ders 105 - Finally Bloğu
Programımızda hata ile karşılaştığımızda yapmamız gereken şeyi önceki
dersimizde öğrendik. Şimdi ise başka bir bloktan bahsedeceğiz. try catch bloklarında bir takım işlemler yaptık. Hata yakalandığında catchiçerisine
işlemlerimizi yazdık. Peki, hata yakalansa da yakalanmasa da yapılmasını
istediğimiz şeyleri nereye yazacağız?
Daha sonra göreceğimiz io, yani dosyaya yazma ve dosyadan veri
okuma işlemlerinde hata olsa da olmasa da dosyamızı kapatmamız
gerekir. finally bloğu genelde bu işlemler için kullanılır. Başka bir örnek
verirsek, veritabanı işlemlerinde veritabanı bağlantı işlemlerini try içerisinde
yaparız. Eğer bir hata olsa da olmasa da veritabanı ile olan bağlantımızı
kapatırız.
Biz bu IO konularına değinmediğimiz için normal bir örnek üzerinde anlatalım.
Bir örnek üzerinde görelim.
1
//Finally.java - 12.04.2014
2
3
public class Finally
4
{
5
public static void main(String[] args)
6
{
7
int dizi[] = new int[]{4, 3, 6};
8
try
9
{
10
System.out.println(dizi[0]);
11
System.out.println(dizi[1]);
12
System.out.println(dizi[2]);
13
System.out.println(dizi[-2]); // hata oluşacak
14
}
15
catch (Exception e)
16
{
17
System.out.println(e.toString());
18
19
20
21
22
23
24
25
26
27
}
finally
{
System.out.println("Burası finally bloğu");
System.out.println("Hata olsa da olmasa da bu bloğa
girildi");
}
}
}
Ekran çıktısı:
4
1
3
2
6
3
java.lang.ArrayIndexOutOfBoundsException:
4
-2
5
Burası finally bloğu
6
Hata olsa da olmasa da bu bloğa girildi
Programımızda try içerisinde görüldüğü gibi bir hata oluşacak. Hata
oluştuğunda hatamızın türünü ekrana yazdırdık. Hata olsa da olmasa
da finally bloğuna girildi. Bu bloğu yazmak zorunlu değildir tabi. Bu blokta ne
varsa, program çıktısında aynen gösterilir.
Dediğimiz gibi bu finally bloğunda genelde açık olan dosyalar ve veritabanı
bağlantıları kapatılır. Çünkü açık olan bir dosya üzerinde işlem yaparsak, hata
ile karşılaşırız.
Istisnalar:
!
JavaSE-7 ile gelen yenilikle beraber, finally bloğunda kapatılması
gereken dosyalar, try bloğunda belirtiliyor. Bu konu detaylı olarak
ileriki derslerimizde incelenecektir.
Ders 106 - Finally Bloğunda Try - Catch Kullanımı
finally bloğu içerisinde tekrar bir try - catch bloğu yazabiliriz. Bunu iç içe
yazdığımız if ifadeleri gibi düşünebiliriz.
Bununla ilgili bir örnek yapalım.
1 //Finally.java - 12.04.2014
2
3 public class Finally
4 {
5
public static void main(String[] args)
6
{
7
int dizi[] = new int[]{4, 3, 6};
8
try
9
{
10
System.out.println(dizi[4]);
11
}
12
catch (Exception e)
13
{
14
System.out.println(e.toString());
15
}
16
finally
17
{
18
try
19
{
20
System.out.println(dizi[1]);
21
}
22
catch (Exception e1)
23
{
24
System.out.println(e1.toString());
25
}
26
}
27 }
28 }
29
30
Ekran çıktısı:
java.lang.ArrayIndexOutOfBoundsException:
1
4
2
3
İlk try içerisinde hata ile karşılaştığımız için catch bloğuna girildi ve hatamız
ekrana yazdırıldı. Daha sonra her şartta girilmesi gereken finally bloğuna
girildi. Bu blok içerisindeki try bloğunda da bir ifade yazdırdık. Fakat burada
bir hata olmadığı için dizi[1] ifadesini ekrana yazdırdı.
Bu yöntem de yine aynı şekilde dosyada okunacak veri kalmadıysa dosyanın
kapatılması gibi işlemlerde kullanılır.
Ders 107 - Birden Fazla Hata Yakalama
Uygulama geliştirirken bazen bir kod bloğu arasında birden fazla hata tipiyle
karşılaşabiliriz. Bu gibi durumlar için birden fazla catch bloğu tanımlamak
daha uygundur. Bu sayede uygulamamız hata tiplerine karşı daha duyarlı hale
gelecektir.
Genel Yapısı:
try
1 {
2
// hata kontrolü yapılacak kod
3 }
4 catch (Hata_türü1 e)
5 {
6
// Hata_türü1 hatası olduğunda çalışacak
7 blok
8 }
9 catch (Hata_türü2 e)
10 {
11
// Hata_türü2 hatası olduğunda çalışacak
12 blok
}
Yukarıdaki gibi tanımladığımız ikinci catch bloğu sayesinde kod
bloğu, Hata_türü2 tipindeki hatalara da duyarlıu hale geldi. Örnekteki gibi
daha fazla catch bloğu tanımlamamız mümkündür. Bunu switch yapısına
benzetebiliriz. Hangisine uyarsa, o catch bloğuna girer.
Bir örnek verelim:
1
//CokluHataYakalama.java - 12.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.*;
public class CokluHataYakalama
{
public static void main(String[] args)
{
char veriler[] = new char[1000];
File f = new
File("C:\\Kitap\\hatayakalama.txt");
// dosya adresi verildi
try
{
FileReader fr = new FileReader(f);
fr.read(veriler); // dosyadan veri okuma
yapıldı
String veri = new String(veriler);
System.out.println(veri);
}
catch (IOException e) // bu bloğa girilecektir
{
System.out.println("Hata oluştu: ");
System.out.println(e.toString());
}
catch (ArrayIndexOutOfBoundsException
e2)
{
System.out.println("Hata oluştu: ");
System.out.println(e2.toString());
}
}
}
Ekran çıktısı:
Hata oluştu:
1
java.io.FileNotFoundException: C:\Kitap\hatayakalama.txt (Sistem belirtilen yolu
2
bulamıyor)
İleriki derslerimizde anlatacağımız dosya okuma ve yazma işlemleri ile ilgili
bir örnek verdik. En yukarıda belirttiğimiz adreste öyle bir dosya
bulunmamaktadır. O yüzden bu dosyadan bir veri okuyamayız. Dolayısıyla
ilk catch bloğuna girecektir. Çünkü io, yani giriş çıkış ile ilgili bir hata aldık.
Eğer bunlardan önce, indeksi olmayan bir dizinin elemanına erişmeye
çalışsaydık,o zaman 2. catch bloğuna girecekti.
Ders 108 - Throw Anahtar Kelimesi
Geliştirici uygulamanın herhangi bir yerinde kendisi Exception verebilir ve
daha sonra throw kelimesiyle fırlattığı bu Exception'u başka bir yerde
kullanabilir. Örnek olarak yine 0'a bölme örneğine bakalım.
1
//ThrowKullanimi.java - 12.04.2014
2
3
import java.util.Scanner;
4
5
public class ThrowKullanimi
6
{
7
public static int sayiBol (int sayi1, int sayi2)
8
{
9
if (sayi2 == 0)
10
{
11
throw new ArithmeticException("İkinci sayı 0(sıfır)'dan farklı
12
olmalı");
13
}
14
int sonuc = sayi1 / sayi2;
15
return sonuc;
16
}
17
18
public static void main(String[] args)
19
{
20
Scanner sc = new Scanner(System.in);
21
try
22
{
23
System.out.println("İlk sayıyı giriniz");
24
int a = sc.nextInt();
25
System.out.println("İkinci sayıyı giriniz");;
26
int b = sc.nextInt();
27
int sonuc;
28
sonuc = sayiBol(a, b);
29
System.out.println("Sonuc: " + sonuc);
30
}
31
catch (NullPointerException ne)
32
{
33
System.out.println(ne.toString());
34
35
36
37
}
}
}
Ekran çıktısı:
İlk sayıyı giriniz
1
3
2
İkinci sayıyı giriniz
3
0
4
Exception in thread "main" java.lang.ArithmeticException: İkinci sayı
5
0(sıfır)'dan farklı olmalı
6
at ThrowKullanimi.sayiBol(ThrowKullanimi.java:11)
7
at ThrowKullanimi.main(ThrowKullanimi.java:27)
Yukarıdaki örnekte görüldüğü gibi uygulama önce sayıların girilmesini
bekliyor. Sayılar girildikten sonrasayiBol metoduna referans olarak
ekliyor. sayiBol metodu içerisinde payda 0 ise; ArithmeticExceptionveriyor
ve main metodundaki try - catch bloğu, bu hatayı
yakalıyor. sayiBol() metodumuzun içerisinde oluşan hataya göre hata mesajı
yazabiliyoruz. Eğer hata olmazsa if koşuluna zaten girmeyecek ve program
normal akışında ilerleyecektir.
Ders 109 - Throws Anahtar Kelimesi
Bazı metotlar, içerisinde hata oluşturabilecek bir kod içerir. Önceki
derslerimizde öğrendiğimiz yöntemlerde biz hata oluşabilecek kodları try catch içerisine alıyorduk ve bir hata verdiğinde, onu kontrol altına alarak
programın durmasını engelliyorduk.
Peki, biz hatamızı o metot içerisinde değil de başka bir yerde kontrol edebilir
miyiz?
Bir örnek verelim ve onun üzerinden anlatalım.
1
//ThrowKelimesi.java - 21.04.2014
2
3
public class ThrowsKelimesi
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
public void metod1()
{
int dizi[] = new int[] {2, 5, 4};
try
{
System.out.println("Burası
metod1'dir");
System.out.println(dizi[3]);
}
catch (Exception e)
{
System.out.println(e.toString());
}
}
public void metod1Cagir()
{
System.out.println("Burası metod1'i
çağırır");
metod1();
}
public static void main(String[] args)
{
ThrowsKelimesi t1 = new
ThrowsKelimesi();
t1.metod1Cagir();
}
}
Ekran çıktısı:
Burası metod1'i çağırır
1
Burası metod1'dir
2
java.lang.ArrayIndexOutOfBoundsException:
3
3
1.
metod1() içerisinde hataya sebep olabilecek bir işlem yaptık ve hata
verildi. Biz bu hatayı Exceptionhata tipi ile kontrol ettik. Bu örnekte
hangi hatanın vereceğini biliyoruz, fakat eğer bilmemiş olsaydık genel
olarak Exception hata tipini kullanırdık. Çünkü o bize çıktıda zaten
hangi hatadan kaynaklandığını söyleyecektir.
2.
Bu metod1'i metod1Cagir() adlı metot içerisinden
çağırdık. main metodumuzda da bu sınıftan bir nesne
oluşturup metod1Cagir() adlı metodu çağırdık.
3.
Ekran çıktımız tahmin ettiğimiz gibi oldu. metod1() çağırılana kadar
herşey normal, fakat metod1()'in içerisine girildiğinde bir hata ile
karşılaşıldı ve verilen hata nesnesi üzerinden toString() metodu
çağırılarak hatamızın sebebi yazdırıldı. Gördüğümüz gibi hatanın
tipini Exception olarak verdik, fakat çıktımızda hatamızın
tipini ArrayIndexOutOfBoundsException olarak verdi. Yani
hatamızın sebebiniException tipini kullanarak da öğrenebiliriz.
Şimdi gelelim asıl konumuza... Yukarıdaki örnekte hata kontrolü, içinde
bulunulan metot tarafından gerçekleştirildi. Peki, biz hata kontrolünü burada
yapmak istemiyorsak ne yapmalıyız? Bunun için yapmamız gereken, hata
kontolünü metodumuzun çağırıldığı yerde yapmaktır.
Metodun çağırıldığı yerde try - catch mekanizması kurulur. Hatamızın
oluşabileceği metotta ise throwsanahtar kelimesi kullanılır. Bu anahtar kelime
sayesinde, metot içerisinde bir hata oluştuğunda hatayı içeren nesne,
çağırıldığı metoda aktarılır.
Yukarıdaki örneği bir de throws anahtar kelimesi ile yapalım.
1
//ThrowKelimesi2.java - 21.04.2014
2
3
public class ThrowsKelimesi2
4
{
5
public void metod1() throws Exception
6
{
7
int dizi[] = new int[] {2, 5, 4};
8
System.out.println("Burası metod1'dir");
9
System.out.println(dizi[3]);
10
}
11
12
public void metod1Cagir()
13
{
14
System.out.println("Burası metod1'i çağırır");
15
try
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
metod1();
}
catch (Exception e)
{
System.out.println(e.toString());
}
System.out.println("Metod1 çağırıldı");
}
public static void main(String[] args)
{
ThrowsKelimesi2 t1 = new ThrowsKelimesi2();
t1.metod1Cagir();
System.out.println("metod1Cagir() metodu
çağırıldı");
}
}
Ekran çıktısı:
Burası metod1'i çağırır
1
Burası metod1'dir
2
java.lang.ArrayIndexOutOfBoundsException:
3
3
4
Metod1 çağırıldı
5
metod1Cagir() metodu çağırıldı
Hemen açıklamasını yapalım.
1.
metod1() içerisinde bir try - catch kullanmadık. Throws anahtar
kelimesini, metot adından sonra yazdık ve oluşabilecek hata tipini de
en sona yazdık. Yani ifademiz şu şekilde oldu.
public void metod1() throws
1
Exception
2.
Bunu yaparak "Eğer bu metodda bir hata oluşursa, hatayı bir üst
metoda aktar. Bizi çağıran metot bu hata ile ilgilensin." dedik.
3.
Bunu çağıran metod1Cagir() metodunda ise try - catch kontrolünü
kurduk. Bu kontrolün içerisinde de metodumuzu çağırdığımız satırı
ekledik. Eğer bir hata olursa da e nesnesi üzerinden bu hatayı
yazdırdık. Bu e nesnesi, aslında metod1'e ait bir nesnedir. Yani
oradaki hatanın bilgilerini tutar.
4.
main() metodumuzda da, yani programımızın başladığı metotta da
bu metod1Cagir() metodunu çağırdık. Çağırdıktan sonra da
bir String yazdırdık. Görüldüğü gibi hata oluşsa da bu metin ekrana
yazıldı. Yani bu da demek oluyor ki programımız çökmedi.
throws anahtar kelimesinin kullanılma amacı budur. Hangi metottaki bir hatayı
bir üst metoda fırlatmak istiyorsak, o metodu throws ile işaretlemeliyiz.
Eğer metot içerisinde throws ile işaretlenmiş metodu çağırırken Exception'u
yakalamak istemiyorsanız, o metodu da throws anahtar kelimesi ile
işaretlemeniz gerekir. Burada önemli olan throws ile işaretlediğiniz her
fonksiyonu ya try - catch bloğu arasında çağıracaksınız ya da throws ile
işaretlenmiş metodu çağırdığınız metodu da throws anahtar kelimesi ile
işaretleyeceksiniz. Örneğin;
public class sinif
1
{
2
public void fonksiyon() throws
3
Exception
4
{
5
// hata oluşturabilecek kodlar
6
}
7
8
public void fonksiyon2() throws
9
Exception
10
{
11
fonksiyon();
12
}
}
Yukarıda görüldüğü gibi throws anahtar kelimesi ile
işaretlenmiş fonksiyon, fonksiyon2 tarafından çağırılıyor ve fonksiyon2 hatayı
yakalamayacağını throws anahtar kelimesiyle belirtiyor. Yani fonksiyon2 de
hatayı kontrol etmeyip, kendini çağıran metoda aktarıyor. fonksiyon2'yi
çağıran fonksiyonu da throwsanahtar kelimesi ile işaretlemeliyiz veya try catch bloğu ile hatayı yakalamalıyız.
Örneğin:
//ThrowKelimesi3.java - 21.04.2014
1
2
public class ThrowsKelimesi3
3
{
4
public void metod1() throws Exception
5
{
6
int dizi[] = new int[] {2, 5, 4};
7
System.out.println("Burası metod1'dir");
8
System.out.println(dizi[3]);
9
}
10
11
public void metod2() throws Exception
12
{
13
System.out.println("Burası metod2'dir");
14
metod1();
15
}
16
17
public static void main(String[] args)
18
{
19
ThrowsKelimesi3 t1 = new ThrowsKelimesi3();
20
try
21
{
22
t1.metod2();
23
} catch (Exception e)
24
{
25
System.out.println(e.toString());
26
}
27
System.out.println("Main metodunda hata kontrolü
28
yapıldı");
29
}
30
}
31
32
Ekran çıktısı:
Burası metod2'dir
1
Burası metod1'dir
2
java.lang.ArrayIndexOutOfBoundsException:
3
3
4
Main metodunda hata kontrolü yapıldı
Bu örnekte metod1 içerisinde oluşan hata, throws ile çağırıldığı yer
olan metod2'ye fırlatıldı. metod2 de bu hatayı kabul etmeyip throws ile
çağırıldığı yere verdi. Bu metot da main içerisinden çağırıldığı için
mecburenmain metodunda try - catch kullanmak zorunda kaldık.
Yani metod1'de kontrol edilmesi gereken hata, fırlatılarak son nokta
olan main içerisinde kontrol edildi. Buradaki e nesnesi de, metod1'deki hatadır.
Fırlatıldığı zaman hata ile ilgili bilgileri bünyesinde taşımıştı.
Eğer main içerisinde de kontrol etmeseydik programımız zaten hiç
çalışmayacaktı.
throws anahtar kelimesini kullanırken unutulmaması gereken, bir diğer önemli
nokta ise işaretlenen hata tipidir. İlk işaretlediğimiz fonksiyon
metodu Exception hata tipiyle işaretlenmişti. Dolayısıyla bu metodu çağıran
metotlar bu hata tipine karşı duyarlı olmak zorunda veya kendisini de bu hata
tipine karşı throwsanahtar kelimesi ile işaretlemelidir.
Ders 110 - Exception Türü Oluşturma
Java kütüphanelerinde birçok hata türüne karşı hata tipi tanımlanmıştır. Ancak
bazı durumlarda özel hata tipi tanımlamamız gerekebilir. Bu hatanın
anlaşılabilirliğini artıracak ve çözüm üretmemizi daha da kolaylaştıracaktır.
Böyle durumlarda Exception sınıfını miras alan bir alt sınıf türetmemiz
gerekecektir.
Örneğin:
1 //hataTipim.java - 21.04.2014
2
3 public class hataTipim extends Exception
4 {
5
String hataMetni = "Özel hata tipi";
6
String hataTipi = "hataTipim";
7
8
public void hataTipim()
9
{
10
// yapıcı metod
11
}
12
13
public String toString()
14
{
15
hataMetni += String.format(" : " + hataTipi);
16
// toString metodu ile hata ile ilgili bilgiler
17 gönderilir
18
return hataMetni;
19
}
20 }
21
Yukarıdaki örnekte görüldüğü gibi hataTipim isminde bir hata tipi tanımladık.
Hata metnini göndermek için diğer Exception sınıflarında da olduğu
gibi toString() metodunu kullanmak yeterli olacaktır.
//sinif.java - 21.04.2014
1
2
public class sinif
3
{
4
public void fonksiyon() throws
5
hataTipim
6
{
7
throw new hataTipim();
8
// metod içerisine yazılacak kodlar
9
}
10
}
11
12
Sınıf içerisinde metodumuzu throws anahtar kelimesi ve kendi hata tipimizle
işaretledik.
1 //Throws.java - 21.04.2014
2
3 public class Throws
4 {
5
public static void main(String[] args)
6
{
7
sinif nesne = new sinif();
8
try
9
{
10
nesne.fonksiyon();
11
}
12
catch (hataTipim ht)
13
{
14
System.out.println(ht.toString());
15
}
16 }
17 }
18
19
En son olarak sınıf içerisinde kendi hata tipimizle işaretlediğimiz metodu try catch bloğu yardımıyla hatayı yakalamaya zorlamamız gerekiyor. Böylece
kendi hata tipimizi tanımlamış olduk. Hata tipi içerisinde kullanılan metotlar,
sadece toString() metodu ile sınırlı değildir. Exception sınıflarının kullandığı
ortak metotlar vardır. Bunları da hata sınıfımız içerisinde kullanabiliriz.
Hata mesajlarını elde etmede kullanabileceğimiz bazı Exception sınıfı ortak
metotları şunlardır:

String getMessage(): Oluşan hata ile ilgili bilgiyi içeren mesajı
gönderir. Ancak hatanın tipi ile ilgili bilgi içermez.

String toString(): Oluşan hata ile ilgili detaylı bilgi içeren mesajı
gönderir. Gönderilen mesaj içerisinde hata tipi ":" işareti ve hata
mesajı bulunmaktadır.

String getLocalizedMessage(): Oluşan hata ile ilgili yerel bir mesaj
gönderir. getMessage()metodundan farkı alt Exception sınıfları bu
metodu override yaparak hata mesajını yerelleştirebilirler.

Void printStackTrace(): Oluşan hatanın sebebi ve hatanın hangi
satırda oluştuğu ile ilgili bilgiyi konsola yazdırır.
Ders 111 - Hata Türleri
Bazı hata türlerinin ne anlama geldiğini bilmek işimizi kod yazarken daha da
kolaylaştıracaktır. Bilgiğimiz gibi hatalar, tiplerine göre ayrılmaktadır. En çok
karşılaşılan bazı hata türleri ve açıklamaları şöyledir:
0'a bölme gibi mantıksal matematik
hatalarında oluşur.
Dizinin indeksinin aşılması durumunda
oluşur. Diziye boyutundan fazla eleman
ArrayIndexOutOfBoundsException yüklemek veya dizinin olmayan
indeksine erişmek başlıca yapılan
hatalardır.
Herhangi bir nesne değişkenine ilk
değer atanmadan kullanılmaya çalışılırsa
NullPointerException
oluşur.
Oluşturulmamış bir dosyaya erişim
FileNotFoundException
durumunda bu hata meydana gelir.
Karakteri okuyamamak gibi genel
IOException
giriş/çıkış hataları.
Sayı girilmesi gereken yerde karakter
NumberFormatException
girilmesi durumunda oluşur.
Diziye kendi türü dışında veri girilmesi
ArrayStoreException
durumunda oluşur. (tip uyuşmazlığı)
Herhangi bir nesne değişkenine farklı tip
ClassCastException
değer girilmesi durumunda oluşur.
String'de var olmayan bir indekse
StringIndexOutOfBoundsException erişilmeye çalışılması durumunda
oluşur.
ArithmeticException
Java'da bütün hata tipleri Throwable hata tipinden türemişlerdir. Biz
programlarımızda, hangi tür hatanın verilebileceğini bilmediğimiz için her
hatayı Exception tipinde belirledik.
Diyelim ki throws ile bir hata nesnesini, çağırıldığı metoda aktardık. Bu
metotta hata nesnemizi yakalayabilmek için kullanmamız gereken hata tipi,
hatanın olduğu tipi kapsamalıdır. Bunu örnek ile şöyle açıklayalım.
1
//ThrowsKelimesi.java - 21.04.2014
2
3
public class ThrowsKelimesi
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
public void metod1() throws Exception
{
int x = 0, y = 4;
System.out.println(y / x);
}
public void metod2()
{
try
{
metod1();
}
catch (ArithmeticException e)
{
System.out.println(e.toString());
}
}
public static void main(String[] args)
{
ThrowsKelimesi nesne = new
ThrowsKelimesi();
nesne.metod2();
}
}
Ekran çıktısı:
Exception in thread "main" java.lang.Error: Unresolved compilation
1
problem:
2
Unhandled exception type Exception
3
4
at ThrowsKelimesi.metod2(ThrowsKelimesi.java:15)
5
at ThrowsKelimesi.main(ThrowsKelimesi.java:26)
Örneğimizde hatamızı Exception tipi ile verdik. Fakat bu hatayı kontrol
ederken ArithmeticException ile kontrol etmeye çalıştık. Bu hata verecektir.
Çünkü yakalamaya çalıştığımız ArithmeticException tipi,
aktardığımız Exception tipinden daha az kapsamlıdır. Yakalamaya çalıştığımız
tipin daha kapsamlı olması gerekir. O yüzden diğerleri kapsayan tip
olan Exception tipi ile biz programlarımızdaki hataları yakalamaya çalıştık.
Bütün hata tiplerinden yola çıkarak programımızda oluşan hataları 2 grupta
toplayabiliriz. Şimdi bunları inceleyelim.
RUNTIMEEXCEPTION HATA TÜRÜ
Runtime kavramını, diğer programlama dillerinden de duymuş olabilirsiniz.
İsminden de anlaşılacağı üzereruntime exception hataları, çalışma
zamanında meydana gelen hatalardır.
Diyelim ki programımız normal akışında ilerliyor. Kullanıcı int tipinde veri
girmesi gereken yerde Stringtipinde bir veri girdi. Biz bu girilen değeri
değişkene atadığımız yerde try - catch kullanmadıysak, program çalışırken hata
verecektir. Bunlar Runtime Exception hatası olarak bilinir. Yani çalışma
sırasında oluşan hatalardır.
Derleme anında da hatalar oluşabilir. Java, derleme hatasında oluşabilecek
hatalara karşı bizi uyarmaz. Yazılımcının, yazdığı kodlara dikkat etmesi
gerekir. Yazdığımız bazı kodları mutlaka try - catch içerisine yazmamız
gerektiğini söyleyecektir. Mesela; dosya bağlantılarında try - catch koymamızı
ister. Fakat çalışma anında oluşan hatalar için Java, önceden bir uyarı vermez.
Programın akışında bu hataya rastladığında hatasını verir. Yani kullanıcının
girdiği veriyi int değişkenine atsın dediğimizde, burada hata yoktur.
KullanıcıString değer girerse program çalışırken hata verir.
ÇÖZÜLEMEYEN HATALAR (ERROR)
Bu tür hatalar için verilebilecek en önemli örnek, belleğin yetmediği
durumlardır. Bu tür hataları ne kadartry - catch içerisine alsak da hatayı
çözemeyiz. Bazen bellekte gereksiz yere kullanılmayan nesneler bulunur. Bu
kullanılmayan nesneler de, bu tür hatalara sebep olabilir.
Ders 112 - I/O Kavramına Giriş
Giriş çıkış işlemleri genelde, bir dosyadan verileri okumak veya bir dosyaya
verileri yazmak için kullanılır. Dosyalar arasında veri aktarımı yapmanın
dışında ağ üzerinden de bunu gerçekleştirebilir.
Biz bu dosyadan okuma ve dosyaya yazma işlemlerini konsol üzerinden
anlatacağız. Normalde giriş çıkış işlemleri için applet'ler kullanılsa da bunu da
öğrenmekte fayda var. Çok kullanılan bir yapı olmasa bile verileri text üzerinde
tutmak için kullananlar vardır. Verileri depolamak, istenildiğinde çekip
okumak, başka bir dosyaya yazmak için de kullanılır
Giriş çıkış işlemleri için kullanmamız gereken paket java.io paketidir.
Yazacağımız programlarda bu paketiimport etmemiz gerekiyor. Bu paketin
içerisinde ileriki derslerimizde anlatacağımız sınıflar bulunur. Konsol ile
çalıştığımız için bu paketi kullanıyoruz. Okuma yazma işlemleri için konsol
dışındaki yöntemleri kullanırsak başka bir paket ile çalışmalıyız. Son
zamanlarda yeni geliştirilen NIO (java.nio) paketi ile, daha ileri düzeyde ve
daha performanslı giriş çıkış işlemleri yapılabilmektedir.
Java'da giriş çıkış işlemleri Stream mantığı ile yapılır. Akım anlamına gelen
Stream, programımız ile dosya arasında köprü görevi görür. Yani bir nevi
verilerin iletildiği kanaldır.
Java'da veri aktarım işlemlerini, karakter bazlı ve byte bazlı olarak ikiye
ayırabiliriz.
Karakter bazlı aktarım işlemi, verileri karakter halinde taşır. Unicode desteği
vardır. Yani diğer alfabeleri destekler. Byte bazlı aktarım işleminde
ise karakter toplulukları halinde aktarım yapılır. Bu yöntem, karakter bazlı
aktarıma göre daha performanslıdır.
KARAKTER TABANLI VERİ TAŞIMA
Karakter tabanlı veri iletimi, Writer ve Reader sınıfları ile yapılır. Bu sınıflar
da kendi içerisinde alt sınıflara ayrılır. Karakter tabanlı
işlemlerde Unicode desteği vardır.
Reader sınıfı kendi içinde alt sınıflara ayrılır. Bunlardan bazıları:

InputStreamReader

BufferedReader

FileReader

FilterReader

StringReader
Writer sınıfı kendi içerisinde alt sınıflara ayrılır. Bunlardan bazıları:

OutputStreamWriter

BufferedWriter

FileWriter

FilterWriter

StringWriter

PrintWriter
Bu sınıflarla çalışmak için her bir sınıfı ayrı ayrı import etmek gerekir. Bunun
yerine java.io.* sınıfınıimport ederek bütün sınıfları kullanabiliriz.
Bu alt sınıflardan birkaçını anlatacağız. Konu başlığı altında detaylarına
ineceğiz.
BYTE TABANLI VERİ TAŞIMA
Byte tabanlı veri iletimi InputStream ve OutputStream sınıfları ile yapılır.
Java'daki tüm sınıflar Objectsınıfından türediği için bu sınıflar
da Object sınıfından türemişlerdir. Byte tabanlı işlemlerde Unicode desteği
yoktur.
InputStream kendi içinde alt sınıflara ayrılır. Bunlardan bazıları:

BufferedInputStream

DataInputStream

FilterInputStream

PrintStream

RandomAccessFile

FileInputStream
OutputStream de kendi içerisinde alt sınıflara ayrılır. Bunlardan bazıları:

BufferedOutputStream

DataOutputStream

FileOutputStream

FilterOutputStream
Bu sınıflarla çalışmak için her bir sınıfı ayrı ayrı import etmek gerekir. Bunun
yerine java.io.* sınıfınıimport ederek bütün sınıfları kullanabiliriz. Biz
örneklerimizde her iki yolu da kullandık.
Istisnalar:
!
Byte ve karakter tabanlı işlemlerde kullanılan sınıfların isimleri size
karışık gelmiş olabilir. Eğer read ve writekelimeleri varsa, o
sınıf karakter tabanlı işlem
yapar. OutputStream veya InputStream ile bitiyorsa byte
tabanlı işlem yapar.
Istisnalar:
!
Her iki yöntemde de buffer kullanılır. Türkçesi tampon olan buffer,
verileri aktarırken bir ara katmandır. Veriler yazılmadan veya
okunmadan önce burada tutulur.
Istisnalar:
!
Bir dosya üzerinde işlem yaptıktan sonra o, dosyayı
kapatmadan tekrar o dosya üzerinde bir işlem yapmak istersek hata
alabiliriz.
Ders 113 - File Sınıfının Kullanımı
Bu sınıf, bilgisayar üzerindeki bir dosyanın bilgilerine erişmeyi
sağlar. File sınıfını bilgisayar üzerindeki herhangi bir dosya ile ilişkilendirerek,
bu dosya hakkında birçok bilgiye ulaşırız. Bu sınıfın yapıcısına, işlem
yapacağımız dosya veya klasörün path adresini veririz. Bu path, dosyanın
bilgisayar üzerindeki adresidir.
Kullanımı:
File f = new File("Dosya
1
Yolu");
File sınıfının f adında bir nesne oluşturduk. Dosya işlemleri bu nesne üzerinden
yapılır. Parantezler içerisine de işlem yapılacak dosyanın yolu verilmelidir.
Bu File sınıfı, dosya ve klasörler için kullanılır.
Örnek bir dosya yolu verelim:
1 C:\elektroarge\java\io.txt;
2 D:\Resimler\manzara.jpg;
Windows işletim sisteminde klasör adları birbirinden \ ile ayrılırken, Linux
ortamında / ile ayrılırlar. Biz Windows üzerinde çalıştığımız için \ kullandık.
Ayrıca yukarıda tek \ ile ayırdık. Programlarımızda çift \\ ile ayırma yapacağız.
Çünkü bir String ifadesinde \ koyduğumuzda Eclipse bunu boşluk bırakma, alt
satırda inme gibi işaretler olarak algılıyor.
Dosyamızın ya da klasörümüzün yolunu, doğrudan yapıcıya göndermek yerine
bir String nesnesine atıp, o nesneyi de gönderebiliriz. Örnek verirsek:
String dosyaYolu =
1
"C:\\elektroarge\\java.txt;
2
File f = new File(dosyaYolu);
Şimdi bu f nesnesi üzerinden erişebileceğimiz metotlardan bazılarına bakalım.
Bu metotlar, dosyamız üzerinde bazı kontrolleri yapar.
Istisnalar:
!
Buradan sonraki anlattığımız konularda, parametre olarak
verdiğimiz path değişkeninde belirtilen dosyayı, önceden sizin kendi
bilgisayarınızın o dizininde oluşturduğunuzu varsayıyoruz.
CREATENEWFILE METODU İLE DOSYA OLUŞTURMA
Bu metot, belirtilen adreste yeni bir dosya oluşturur. Örnek verirsek:
1
//FileSinifi.java - 21.04.2014
2
3
import java.io.File;
4
import java.io.IOException;
5
6
public class FileSinifi
7
{
8
public static void main(String[] args)
9
{
10
File f = new File("C:\\elektroarge\\ornek2.txt");
11
try
12
{
13
14
15
16
17
18
19
20
21
22
f.createNewFile(); // yeni dosya oluşturuldu
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Belirtilen adres yanlış ise, kaydın eklenmesinde hata olabileceği için try
catch içerisinde işlemlerimizi yaptık. Bu metot ile belirtilen
dizinde ornek2 adında bir dosya oluşturduk.
GETNAME METODU İLE DOSYANIN ADINI ÖĞRENME
Bu metot, dosyamızın adını verir. Örnek üzerinde gösterelim.
//FileSinifi2.java - 21.04.2014
1
2
import java.io.File;
3
4
public class FileSinifi2
5
{
6
public static void main(String[] args)
7
{
8
File f = new
9
File("C:\\elektroarge\\ornek2.txt");
10
System.out.println(f.getName());
11
}
12
}
13
14
Ekran çıktısı:
1
ornek2.txt
Bu metot ile dosyamızın ismini öğrendik.
GETABSOLUTEPATH METODU İLE DOSYANIN YOLUNU
ÖĞRENME
Bu metot, bize dosyamızın yolunu verir.
//FileSinifi3.java - 21.04.2014
1
2
import java.io.File;
3
4
public class FileSinifi3
5
{
6
public static void main(String[] args)
7
{
8
File f = new
9
File("C:\\elektroarge\\ornek2.txt");
10
System.out.println(f.getAbsolutePath());
11
}
12
}
13
14
Ekran çıktısı:
1 C:\elektroarge\ornek2.txt
DELETE METODU İLE DOSYAYI SİLME
delete() metodu, dosyamızı bulunduğu dizinden siler. Örnek verirsek:
1
//FileSinifi4.java - 21.04.2014
2
3
import java.io.File;
4
5
public class FileSinifi4
6
{
7
public static void main(String[] args)
8
{
9
File f = new
10
File("C:\\elektroarge\\ornek2.txt");
11
f.delete();
12
System.out.println(f.exists()); // dosya var
13
mı?
14
}
15
}
Ekran çıktısı:
1
false
Dosyamızı sildikten sonra exist() metodu ile var olup olmadığının kontrolünü
yaptık. Dosyamızı sildiğimiz için false değeri döndü.
MKDIR METODU İLE KLASÖR OLUŞTURMA
DOS komutları ile çalıştıysanız, bu isim size yabancı gelmeyecektir. Bu metot,
belirtilen yola belirtilen isimdeki klasörü oluşturur.
//FileSinifi5.java - 21.04.2014
1
2
import java.io.File;
3
4
public class FileSinifi5
5
{
6
public static void main(String[] args)
7
{
8
File f = new
9
File("C:\\elektroarge\\örnekklasör");
10
f.mkdir();
11
}
12
}
13
14
f nesnemize verdiğimiz adreste örnekklasör adlı klasör oluşturuldu.
RENAMETO METODU İLE DOSYANIN ADINI DEĞİŞTİRME
Bu metot, dosya adımızı değiştirmek için kullanılır. Bu metot, içerisine,
yeni bir File tipinde nesnevermemiz gerekiyor.
//FileSinifi6.java - 22.04.2014
1
2
import java.io.File;
3
4
public class FileSinifi6
5
{
6
public static void main(String[] args)
7
{
8
File f = new
9
File("C:\\elektroarge\\veriler.txt");
10
File f2 = new
11
File("C:\\elektroarge\\bilke.txt");
12
f.renameTo(f2);
13
}
14
}
15
Metoda parametre olarak f2 nesnesini verdik. Bu nesne, yeni dosyamızın yeni
yolunu belirtiyor. Değiştirebilmemiz için aynı klasörde olması gerekir.
CANREAD VE CANWRITE METODLARI İLE YAZMA OKUMA
KONTROLÜ
Adından da anlaşıldığı gibi bu metotlar, dosyamızın okunabilirliğini ve
yazılabilirliğini kontrol eder. Duruma göre true veya false değerleri döndürür.
1
//FileSinifi7.java - 22.04.2014
2
3
import java.io.File;
4
5
6
7
8
9
10
11
12
13
14
15
public class FileSinifi7
{
public static void main(String[] args)
{
File f = new File("C:\\elektroarge\\veriler.txt");
if(f.canRead() == true && f.canRead() == true)
System.out.println("Hem yazılabilir hem
okunabilir");
}
}
Ekran çıktısı:
Hem yazılabilir hem
1
okunabilir
Bizim dosyamızın erişiminde herhangi bir kısıtlama olmadığı için iki
kontrolden de true değeri döndü ve ifşartımızın içine girildi. Eğer dosyamızın
yolu yanlış yazıldı ise veya üzerinde herhangi bir kısıtlama var ise falsedeğeri
döner.
File sınıfının metodlarından bazılarını kullanarak son bir örnek vererek
dersimizi bitirelim.
1
//FileSinifi8.java - 22.04.2014
2
3
import java.io.File;
4
5
public class FileSinifi8
6
{
7
public static void main(String[] args)
8
{
9
File f = new File("C:\\elektroarge\\sehirler.txt");
10
if (f.exists()) // böyle bir dosya var ise
11
{
12
System.out.println("Dosya adı : " + f.getName());
13
System.out.println("Dosya yolu : " +
14
f.getAbsolutePath());
15
System.out.println("Dosya boyutu : " +
16
f.getTotalSpace());
17
System.out.println("Dosya okunabilir mi : " +
18
f.canRead());
19
20
}
}
}
Ekran çıktısı:
Dosya adı : sehirler.txt
1
Dosya yolu :
2
C:\elektroarge\sehirler.txt
3
Dosya boyutu : 209609289728
4
Dosya okunabilir mi : true
Bu örneğimizde sehirler.txt adlı dosya üzerinde çalıştık. Eğer dosya var ise,
yani belirtilen klasörde böyle bir dosya mevcutsa istenilen metotlar çalıştırılır.
Temel olarak birkaç metodu inceledik. Bu nesnemiz üzerinden erişebileceğimiz
metotların çokluğu aşağıdaki şekilde görülmektedir.
Ders 114 - FileReader İle Dosya Oluşturma
Bu sınıf ile dosya okuma işlemi yaptığımızda veriler karakter bazlı olarak
okunur. Karakter bazlı işlem yaptığı için karakter encoding vardır. Buffer
kullanılmaz. Performansı düşüktür.
Karakter bazlı işlem yapıldığı için okunan veriler, char tipindeki bir diziye
atılmalıdır. Çünkü işlemler karakter tabanlıdır. Yazma işlemlerinde diziye gerek
yoktur.
1.
FileReader sınıfı ile okumaya yapabilmek için ilk
olarak File sınıfından bir nesne oluşturmak ve bu nesneye dosya
yolunu vermek gerekir.
2.
Daha sonra FileReader sınıfından bir nesne oluşturup, sınıfın
yapıcısına File sınıfından oluşturduğumuz nesneyi parametre olarak
verilmelidir.
3.
Okunan verileri doldurmak için char tipinde bir dizi oluşturulur.
4.
read() metodu ile okunan veriler bu diziye doldurulur.
5.
Doldurulan bu dizi, String tipinde bir nesneye atılır.
6.
Son olarak bu nesne ekrana yazdırılır.
Bu sınıfın kullanımına bir örnek verelim.
1
//FileReaderSinifi.java - 22.04.2014
2
3
import java.io.*;
4
5
public class FileReaderSinifi
6
{
7
public static void main(String[] args)
8
{
9
File f = new
10
File("C:\\elektroarge\\sehirler.txt");
11
char veriler[] = new char[(int) f.length()];
12
try
13
{
14
FileReader f2 = new FileReader(f);
15
f2.read(veriler);
16
String okunan = new String(veriler);
17
System.out.println(okunan);
18
}
19
catch (FileNotFoundException e)
20
{
21
e.printStackTrace();
22
}
23
catch (IOException e)
24
{
25
e.printStackTrace();
26
}
27
}
28
29
}
Ekran çıktısı:
1 İstanbul
2 Edirne
3 Giresun
4 Çorum
5 Samsun
6 Çanakkale
7 Kastamonu
Burada yaptığımız adımları tek tek anlatalım.
1.
File sınıfından f adında bir nesne oluşturduk ve dosya yolunu verdik.
2.
f2 adında bir nesne oluşturduk ve f nesnemizi bu sınıfın yapıcısına
gönderdik.
3.
veriler adında bir char dizisi oluşturduk. Eleman sayısını, dosya
uzunluğu olarak verdik.
4.
f2 nesnesi üzerinden read() metodunu çağırdık. Okunan
veriler, veriler adlı diziye atandı. Yani bu metot, okuduğu verileri bu
diziye doldurdu.
5.
Bu diziyi, okunan adında bir String nesnesine attık.
6.
Son adımda ise, bu okunan nesnesini yazdırdık.
Bu sınıf ile ilgili son bir şey söyleyelim. İçi boş olan bir dosya okunduğu zaman
-1 değeri döner. Aşağıdaki programda a değişkeninin değeri -1 olacaktır.
1
//FileReaderSinifi2.java - 22.04.2014
2
3
import java.io.*;
4
5
public class FileReaderSinifi2
6
{
7
public static void main(String[] args)
8
{
9
File f = new
10
File("C:\\elektroarge\\sehirler.txt");
11
try
12
13
14
15
16
17
18
19
20
21
22
23
{
FileReader f2 = new FileReader(f);
int a = f2.read();
System.out.println("a değeri: " + a);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Ekran çıktısı:
a değeri: 1
1
Sehirler dosyasının içerisindeki tüm bilgileri önceden sildik. Bu dosyadan
okuma işlemi yaptığımızda sonuç olarak -1 değeri dönecektir. Dönen bu -1
değerini bir if içerisine koyarak çeşitli kontroller yapabiliriz. Dosya boş ise
veya dolu ise gibi kontroller koyabiliriz.
Ders 115 - FileWriter İle Dosyaya Yazma
FileWriter sınıfı, FileReader sınıfı gibi karakter bazlı işlem yapar. Yukarıda
saydığımız özellikler, bu sınıf için de geçerlidir. Buffer kullanılmaz.
Performansı düşüktür. Yazma işleminde dizi oluşturmaya gerek yoktur.
Kullanım şekli ve nesne oluşturulması aşağıdaki gibidir.
FileWriter nesne = new FileWriter ("yol",
1
true);
İlk parametre, üzerinde çalışılacak dosyanın bilgisayardaki adresidir. Diğer
parametrenin yazılma zorunluluğu yoktur. Eğer true olarak yazılırsa, o
dosyadaki bilgilerin devamına ekleme yapılır. Eğer yazılmazsa dosyadaki
veriler silinerek yazma işlemi gerçekleştirilir.
Istisnalar:
!
Dosyaya veri yazma işlemlerinde dosyanın kapatılmasına dikkat
edilmelidir. Zorunlu olmasa da hata ile karşılaşabilirsiniz.
Örnek vererek bu sınıfın nasıl kullanıldığına bakalım.
//FileWriterSinifi.java - 22.04.2014
1
2
import java.io.*;
3
4
public class FileWriterSinifi
5
{
6
public static void main(String[] args)
7
{
8
File f = new
9
File("C:\\elektroarge\\bossayfa.txt");
10
try
11
{
12
// yazma işlemleri
13
FileWriter yazdir = new FileWriter(f);
14
String yazilacak = "Bu bir deneme
15
yazısıdır";
16
yazdir.write(yazilacak);
17
yazdir.close(); // bağlantı kapatıldı.
18
// okuma işlemleri
19
char veriler[] = new char[(int) f.length()];
20
FileReader f2 = new FileReader(f);
21
f2.read(veriler);
22
String okunan = new String(veriler);
23
System.out.println(okunan);
24
}
25
catch (IOException e)
26
{
27
e.printStackTrace();
28
}
29
}
30
}
31
Ekran çıktısı:
Bu bir deneme
1
yazısıdır
Burada yaptığımız adımları tek tek anlatalım.
1.
File sınıfından f adında bir nesne oluşturduk ve dosya yolunu verdik.
Bu dosyaya bir şeyler yazacağımız için adını bossayfa koyduk.
2.
yazdir() adında bir nesne oluşturduk ve f nesnemizi bu sınıfın
yapıcısına gönderdik. İşlemlerimizi buyazdir() nesnesi üzerinden
yapacağız.
3.
yazilacak adında bir String oluşturduk ve yazdıracağımız metni bu
değişkene atadık.
4.
yazdir nesnesi üzerinden write() metodunu çağırdık ve parametre
olarak yazdıracağımız değişkeni verdik.
5.
Son olarak bağlantımızı kapattık. Çünkü aynı program içerisinde bir de
okuma işlemi yapacağız. Yazdırdıklarımızı görmek için bu okuma
işlemini yaptık. Okuma işlemini bir önceki konuda anlatıldığı için aynı
şeyleri söylemeyeceğiz.
Istisnalar:
Yazma işleminde, mevcut olmayan bir dosyaya veri yazmak
! istediğimizde hata ile karşılaşmayız. Bu yüzdencatch bloğu sayısını
1'e indirdik. Dosya olmadığı zaman, oluşturulur ve o dosyaya veriler
yazılır. Dolayısıyla bir hata oluşmaz.
Şimdi de okuma ve yazma işlemlerini beraber yapalım, fakat okuduğu verileri
başka bir dosyaya yazsın.
1
//FileReaderSinifi.java - 22.04.2014
2
3
import java.io.*;
4
5
public class FileReaderSinifi
6
{
7
public static void main(String[] args)
8
{
9
File f = new
10
File("C:\\elektroarge\\sehirler.txt");
11
File ff = new
12
File("C:\\elektroarge\\sehirler2.txt");
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
char veriler[] = new char[(int) f.length()];
try
{
// okuma işlemleri
FileReader f2 = new FileReader(f);
f2.read(veriler);
String okunan = new String(veriler);
f2.close();
// yazma işlemleri
FileWriter yazdir = new FileWriter(ff);
yazdir.write(okunan);
yazdir.close(); // bağlantı kapatıldı
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Başka bir dosyaya yazmak için yazılacak dosya için yeni bir File sınıfı nesnesi
ve yeni bir FileWriternesnesi oluşturmak gerekiyor. Bu
yeni FileWriter nesnesine, ikinci oluşturduğumuz nesneyi parametre olarak
gönderiyoruz.
okunan adlı String veriyi de write() metoduna gönderiyoruz. İşimiz bitince de
dosyayı kapatıyoruz.
Ders 116 - FileInputStream İle Dosya Okuma
Bu sınıf ile dosya okuma byte bazlı olarak yapılır. Byte bazlı
okumalarda karakter encoding olmaz.
Byte bazlı işlemlerde, okunan veriler byte tipinde bir diziye aktarılır. Okuma
işlemleri byte bazlı olanlarda bu şekilde yapılır.
Bu sınıfı kullanabilmek için ilk olarak bu sınıftan bir nesne oluştururuz. Daha
sonra bu nesneye, okunacakFile nesnesi parametre olarak verilir.
Istisnalar:
!
Bu sınıfı kullanabilmek için import java.io.FileInputStream; ifadesi
ile bu sınıfı import etmemiz gerekir. Fakat import
java.io.*; ifadesini kullandığımız için buna gerek kalmayacaktır.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStream_FayliOxuma {
public static void main(String[] args) throws
FileNotFoundException, IOException {
File f = new
File("C:\\Users\\Anonymous\\Desktop\\yazi.txt");
byte[] inform = new byte[(int)f.length()];
FileInputStream fis = new FileInputStream(f);
fis.read(inform);
String metin = new String(inform);
System.out.println(inform);
}
}
Istisnalar:
!
Bu sınıf ile okuma işlemi yaptığımızda, bu sınıftan nesne oluştururken
o bloğu try - catch içerisine almamız gerekir. Olmayan bir dosya ile
çalışmak hata verebilir.
Hemen bir örnek ile başlayalım.
1
İstanbul
2
Edirne
3
Ankara
4
Çorum
5
Giresun
Burada yaptığımız adımları tek tek anlatalım.
1.
File sınıfından f adında bir nesne oluşturduk ve dosya yolunu verdik.
2.
oku adında bir nesne oluşturduk ve f nesnemizi bu sınıfın yapıcısına
gönderdik.
3.
dizi adında bir byte dizisini oluşturduk. Eleman sayısını, dosya
uzunluğu olarak verdik.
4.
oku nesnesi üzerinden read() metodunu çağırdık. Okunan
veriler dizi adlı diziye atandı. Yani bu metod, okuduğu verileri bu
diziye doldurdu.
5.
Bu diziyi, okunan adında bir String nesnesine attık.
6.
Son adımda ise bu okunan nesneyi yazdırdık.
Dediğimiz gibi okuma ve bağlantı için try - catch bloğu oluşturduk. Okuma ve
bağlantı hatalarında, hata mesajı ekrana yazılacaktır.
Bu sınıfın genel kullanımı bu şekildedir. Verileri byte olarak okur.
Ders 117 - FileOutputStream İle Dosyaya Yazma
FileOutputStream ile verileri dosyaya yazdırmanın FileWriter sınıfından bir
farkı, byte tabanlı olduğu için dosyaya veri yazdırmak için bir byte
dizisi oluşturmamızdır. Diğerinde char dizisi oluşturmuştuk. Veriler bloklar
halinde aktarılır. Byte tabanlı işlemler bloklar halinde yapılır. Byte tabanlı
olduğunu, sonundaki OutputStreamifadesinden anlıyoruz. Kod olarak çok bir
fark yoktur.
Örnek vererek gösterelim.
1
//FileOutputStreamSinifi.java - 22.04.2014
2
3
import java.io.*;
4
5
public class FileOutputStreamSinifi
6
{
7
public static void main(String[] args)
8
{
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
File yol = new File("C:\\elektroarge\\veriler.txt");
try
{
FileOutputStream yazdir = new
FileOutputStream(yol);
String metin = "FileOutputStream ile Yazdırma";
byte veriler[] = metin.getBytes();
yazdir.write(veriler);
yazdir.close(); // dosya kapatıldı
// okuma işlemleri
char okunacak[] = new char[(int) yol.length()];
FileReader f2 = new FileReader(yol);
f2.read(okunacak); // dizi dolduruldu
String okunan = new String(okunacak);
System.out.println(okunan);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Ekran çıktısı:
FileOutputStream ile
1
Yazdırma
Bu örnekte farklı olarak söyleyeceğimiz
şey getBytes() metodudur. String tipindeki verimizi bytetipindeki diziye atan
metottur. Çünkü bu sınıfın getBytes() metodu yalnızca byte tipinde parametre
alır. Doğrudan String ifademizi veremiyoruz.
Ders 118 - BufferedReader İle Dosyadan Okuma
Reader sınıfından türeyen bu sınıf, karakter tabanlı işlem yapar. Dosyadan
okuma işlemleri buffer kullanılarak yapılır ve performansı fazladır.
Bir örnek verelim:
//BufferedReaderr.java - 22.04.2014
1
2
import java.io.*;
3
4
public class BufferedReaderr
5
{
6
public static void main(String[] args)
7
{
8
try
9
{
10
File f = new
11
File("C:\\elektroarge\\buffer.txt");
12
FileReader fr = new FileReader(f);
13
BufferedReader br = new
14
BufferedReader(fr);
15
String satir = br.readLine();
16
while (satir != null)
17
{
18
System.out.println(satir);
19
satir = br.readLine();
20
}
21
br.close();
22
}
23
catch (Exception e)
24
{
25
e.printStackTrace();
26
}
27
}
28
}
29
Ekran çıktısı:
Bu bir deneme
1
yazısıdır
İlk olarak File sınıfından bir nesne oluşturduk ve yapıcıya dosyanın
yolunu verdik. Daha sonar FileReader nesnesi oluşturduk ve bu sınıfın
yapıcısına da File sınıfından oluşturulan f nesnesini verdik.
BufferedReader sınıfından oluşturulmuş br nesnesiyle de fr nesnesini
birbirine bağladık. Okuma işlemini readLine() metodu ile yaptık ve dönen
değerleri while döngüsü ile yazdırdık.
BufferedReader sınıfı aynı zamanda kullanıcıdan veri girişine de izin verir. Bu
sınıfı kullanarak klavyeden girilen değeri alabiliriz. Bununla ilgili de bir örnek
yapalım.
//BufferedReaderr2.java - 22.04.2014
1
2
import java.io.*;
3
4
public class BufferedReaderr2
5
{
6
public static void main(String[] args)
7
{
8
try
9
{
10
InputStreamReader is = new
11
InputStreamReader(System.in);
12
BufferedReader br = new BufferedReader(is);
13
14
System.out.println("Birşeyler yazın :");
15
String deger = br.readLine();
16
System.out.println("Girilen: " + deger);
17
br.close();
18
}
19
catch (Exception e)
20
{
21
e.printStackTrace();
22
}
23
}
24
}
25
26
Ekran çıktısı:
Birşeyler yazın :
1
Okan Bilke
2
Girilen: Okan
3
Bilke
Kullanıcıdan veri almak için yine readLine() metodu kullanılır. Bu metot,
girilen input'u boşluklarla beraber alır. BufferedReader sınıfı, veri girişi
kullanacağı zaman InputStreamReader sınıfı ile beraber kullanılır.
Ders 119 - BufferedWriter İle Dosyaya Yazma
Writer sınıfından türeyen bu sınıf, karakter bazlı işlem
yapar. Buffer kullandığı için flush metodu ilebuffer içerisinde bulunan
verilerin dosyaya yazdırılması gerekir.
Bu sınıf, FileWriter sınıfı ile kullanılırken performansı önemli derecede artırır.
Bir örnek yapalım.
//BufferOrnek.java - 22.04.2014
1
2
import java.io.*;
3
4
public class BufferOrnek
5
{
6
public static void main(String[] args) throws
7
Exception
8
{
9
File f = new File("C:\\elektroarge\\buffer.txt");
10
FileWriter fw = new FileWriter(f, false);
11
BufferedWriter yaz = new BufferedWriter(fw);
12
yaz.write("Bu bir deneme yazısıdır");
13
yaz.flush();
14
yaz.close();
15
}
16
}
17
18
FileWriter sınıfından bir nesne oluşturarak yapıcısına File sınıfından
oluşturduğumuz nesneyi verdik. Yanına da false parametresini ekledik. Çünkü
içerideki bilgileri silip yeniden yazmasını istiyoruz. Bu parametreyi
vermeseydik, yine aynı işi yapardı.
Daha sonra BufferedWriter sınıfından bir nesne oluşturuyoruz. Bu sınıfın
yapıcısına fw nesnesini veriyoruz.
Artık bu yaz nesnesi üzerinden write() metodunu çağırarak istediğimiz metni
parametre olarak gönderiyoruz. Bu işlem ile veriler buffer'e yazılır.
Son olarak da flush() metodunu çağırıyoruz ve buffer'da bulunan verileri
dosyaya yazdırıyoruz. Daha sonra dosyamızı kapatıyoruz.
Ders 120 - BufferedInputStream İle Dosya Okuma
Bu sınıf, bir soyut sınıf olan FilterInputStream sınıfından türemiştir. Bu
sınıfın adından şunu anlıyoruz.Buffer kullanarak veri aktarımı yapar ve aynı
zamanda byte tabanlı iletim sağlar. Buffer kullandığı için performans avantajı
vardır.
Byte tabanlı işlem yapıldığı için okuma işleminde bir byte dizisi oluşturulmalı
ve .ekilen elemanlar bu diziye alınmalıdır.
Bu sınıfı, FileInputStream sınıfı ile beraber kullanırız. Bu sınıftan
oluşturduğumuz nesneyi,BufferedInputStream sınıfının yapıcısına göndeririz.
Şimdi bir örnek verelim:
//BufferOrnek.java - 22.04.2014
1
2
import java.io.*;
3
4
public class BufferOrnek
5
{
6
public static void main(String[] args)
7
{
8
File f = new File("C:\\elektroarge\\buffer.txt");
9
byte dizi[] = new byte[1000];
10
try
11
{
12
FileInputStream f2 = new FileInputStream(f);
13
BufferedInputStream bf = new
14
BufferedInputStream(f2);
15
int okunan = 0;
16
while((okunan = bf.read(dizi)) != -1)
17
{
18
String veriler = new String(dizi, 0, okunan);
19
System.out.println(veriler);
20
}
21
bf.close();
22
}
23
catch (IOException e)
24
{
25
e.printStackTrace();
26
}
27
}
28
}
29
30
Ekran çıktısı:
Okan Bilke
1
Elektroarge
BufferedInputStream sınıfının yapıcısına, bir üst satırda
oluşturduğumuz f2 nesnesini verdik. While döngüsü ile -1 dönene kadar yani
dosya sonu gelene kadar okuma işlemi yaptık. Verileri read() metodu ile
okuduk. String tipindeki veriler adlı nesneye okunan kadarını attık. Son olarak
bu veriler nesnesini yazdırdık.
Istisnalar:
!
Buffer kullanarak verileri okumak, aynı zamanda bellekten veri
okumak gibidir. Dolayısıyla diğer yöntemlere göre çok daha hızlı
işlem yapılır.
Ders 121 - BufferedOutputStream ile Dosyaya Yazma
Bu sınıf, bir soyut sınıf olan FilterOutputStream sınıfından türemiştir. Bu
sınıfı kullanırken bir byte dizisi tanımlamaya gerek yoktur. Çünkü okuma
işlemi yapılmadığı için, içi doldurulması gereken bir diziye de ihtiyaç yoktur.
Bu sınıfı, FileOutputStream sınıfı ile beraber kullanırız. Bu sınıftan
oluşturduğumuz nesneyi,BufferedOutputStream sınıfının yapıcısına
göndeririz.
Bir örnek verelim.
1 //BufferOrnek.java - 22.04.2014
2
3 import java.io.*;
4
5 public class BufferOrnek
6 {
7
public static void main(String[] args)
8
{
9
File f = new File("C:\\elektroarge\\buffer.txt");
10
try
11
{
12
BufferedOutputStream bf = new
13 BufferedOutputStream(new FileOutputStream(f));
14
bf.write("Java'yı seviyorum".getBytes());
15
bf.flush(); // buffer içerisindekiler dosyaya yazıldı
16
bf.close(); // dosya kapatıldı
17
}
18
catch (IOException e)
19
{
20
e.printStackTrace();
21
}
22
}
23 }
24
Örnekteki flush() metodu ve write() metodu, BufferedOutputStream sınıfına
ait metotlardır. write() metodunu
kullanırken String verimizin getBytes() metodu ile işlem yapılır. Bu,
metni byte olarak yazmak içindir.
Bu örnekte dikkatimizi çeken bir şey var. try ifadesinden sonraki nesne
tanımlamada, yapıcıya parametre gönderme işleminde aynı anda bir sınıf
oluşturduk ve bu sınıfın yapıcısına da f nesnesini gönderdik. Bu şekilde
tanımlama da yapılabilir. Normal olarak tanımlama yapsaydık aşağıdaki gibi
yapmamız gerekirdi.
FileOutputStream f2 = new FileOutputStream(f);
1
BufferedOutputStream bf = new
2
BufferedOutputStream(f2);
Ders 122 - Scanner Sınıfı İle Dosya Okuma
Scanner sınıfı, kullanıcıdan veri alma görevi gördüğü gibi bir dosyayı da
okuyup ekrana yazdırabilir.
Önceki derslerimizde Scanner sınıfı ile klavyeden veri girişi
yaparken System.in parametresini kullanmıştık. Scanner sınıfı, bu girilen
parametreye göre farklı işler yapabilir. Şimdi bu parametreyi değiştirerek
dosyadaki bilgileri yazdırmaya çalışalım.
Bir örnek verelim ve onun üzerinden anlatalım.
//ScannerSinifi.java - 22.04.2014
1
2
import java.io.*;
3
import java.util.Scanner;
4
5
public class ScannerSinifi
6
{
7
public static void main(String[] args)
8
{
9
File f = new File("C:\\elektroarge\\scanner.txt");
10
try
11
{
12
Scanner s = new Scanner(f);
13
while(s.hasNextLine())
14
{
15
String veri = s.nextLine();
16
System.out.println(veri);
17
}
18
}
19
catch (FileNotFoundException e)
20
{
21
System.out.println("Dosyaya bağlanırken hata
22
oluştu");
23
}
24
}
25
}
26
27
Ekran çıktısı:
1
Okan Bilke
2
Onur Bilke
3
ElektroArge
File sınıfını kullanarak f adında bir nesne oluşturduk. Bu nesnemize de
okunacak verilerin olduğu dosyanın yolunu verdik. Scanner sınıfının yapıcısına
parametre olarak ise, bu f nesnesini gönderdik. Scannersınıfından
oluşturduğumuz s nesnesi ile artık okuma işlemi yapabiliriz.
while döngüsü içerisindeki şartımız, döngünün, dosyada okunacak bir şey
kalmayana kadar devam etmesini sağlar. Bu while döngüsü içerisinde
de nextLine() ile satır satır okuma yaparız ve okuduğumuzu konsola
yazdırırız.
while döngüsünün içerisinde yazdığımız metodu açıklayalım. Bu
metodun nextLine() metodundan ne farkı vardır?

hasNextLine(): Scanner sınıfı eğer bir satır okuyabiliyorsa true,
okuyamıyorsa false değeri döner.

hasNextInt(): Scanner sınıfı eğer bir int değer okuyabiliyorsa true,
okuyamıyorsa false değeri döner.

hasNextFloat(): Scanner sınıfı eğer bir float değer
okuyabiliyorsa true, okuyamıyorsa false değeri döner.

hasNextByte(): Scanner sınıfı eğer bir byte değer
okuyabiliyorsa true, okuyamıyorsa false değeri döner.

hasNextShort(): Scanner sınıfı eğer bir short değer
okuyabiliyorsa true, okuyamıyorsa false değeri döner.
Gördüğünüz gibi bu metotlar, boolean tipinde değer döndürürler. Diğer
bildiğimiz, kullanıcıdan veri alan metotlardan (nextLine) farkı budur. Dosyada
okunacak bir verinin olup olmadığını kontrol etmek için kullanılır. Okunacak
veri yoksa false döner.
Başka bir örnek verelim.
1 //ScannerSinifi2.java - 22.04.2014
2
3 import java.io.*;
4 import java.util.Scanner;
5
6 public class ScannerSinifi2
7 {
8
public static void main(String[] args)
9
{
10
File f = new File("C:\\elektroarge\\scanner.txt");
11
try
12
{
13
Scanner s = new Scanner(f);
14
System.out.println(s.hasNextInt());
15
}
16
catch (FileNotFoundException e)
17
{
18
System.out.println("Dosyaya bağlanırken hata
19 oluştu");
20
}
21
}
22 }
23
Ekran çıktısı:
1
false
Dosyamızda sadece String tipinde veriler olduğu
için hasNextInt() metodundan false değer dönecektir.
Şimdi de dosyamızdaki sayıları okuyup, 2'ye bölünenleri ekrana yazdıralım.
1 //ScannerSinifi3.java - 22.04.2014
2
3 import java.io.*;
4 import java.util.Scanner;
5
6 public class ScannerSinifi3
7 {
8
public static void main(String[] args)
9
{
10
File f = new File("C:\\elektroarge\\scanner.txt");
11
try
12
{
13
Scanner s = new Scanner(f);
14
while(s.hasNextInt())
15
{
16
int sayi = s.nextInt();
17
if(sayi % 2 == 0)
18
System.out.println(sayi);
19
}
20
}
21
catch (FileNotFoundException e)
22
{
23
System.out.println("Dosyaya bağlanırken hata
24 oluştu");
25
}
26
}
27 }
28
Önce dosyamızın içindeki verileri görelim:
Çıktımız ise şu şekilde olacaktır:
1
12
2
78
3
56
Istisnalar:
!
Yukarıda anlattığımız gibi bir dosyadan verileri okuma işleminde
parametre olarak File nesnesi, yani bir dosya vermiştik. Bunun yerine
bir String veri de verebiliriz.
Buna bir örnek vererek dersimizi sonlandıralım.
1 //ScannerSinifi4.java - 22.04.2014
2
3 import java.util.Scanner;
4
5 public class ScannerSinifi4
6 {
7
public static void main(String[] args)
8
{
9
String metin = "ElektroArge Okan
10 Bilke";
11
12
13
14
15
16
17
}
18 }
19
Scanner s1 = new Scanner(metin);
while (s1.hasNext())
{
String a = s1.next();
System.out.println(a);
}
Ekran çıktısı:
1 ElektroArge
2 Okan
3 Bilke
Scanner sınıfının yapıcısına bir String ifade verdik ve işlemlerimizi
bu String üzerinden gerçekleştirdik.
Ders 123 - Scanner Sınıfı Yapıcıları
Scanner nesnesi, Scanner sınıfının farklı yapıcılarına göre farklı işlemler
yapar. System.in parametresi ile kullanıcıdan veri girişi
almıştık. Scanner sınıfının yapıcısına File nesnesi göndererek de dosyadan
okuma yapmıştık. Şimdi bu yapıcı metotları gösterelim.

Scanner (File kaynakDosya) : Dosyayı okuma işlemi yapar.

Scanner (File kaynakDosya, String veriSeti) : Dosyayı okuma
işlemi yapar.

Scanner (String kaynakString) : Bir String ifadeyi okur.

Scanner (InputStream kaynak) : Bir input akımını okuma işlemi
yapar.

Scanner (InputStream kaynak, String veriSeti) : Bir input akımını
okuma işlemi yapar.

Scanner (Readable kaynak) : Bir kaynağı okuma işlemi yapar.

Scanner (ReadableByteChannel kaynak) : Bir kanalı okuma işlemi
yapar.

Scanner (ReadableByteChannel kaynak, String veriSeti) : Bir
kanalı okuma işlemi yapar.
Biz bunlardan dosyadan okuma ve bir String veriden okuma işlemini
yaptık. Diğerlerine girmeyeceğiz.
Ders 124 - Rastgele Erişimli Dosyalarda Okuma ve Yazma
Bu dersimizi anlatmadan önce rastgele erişimli dosyaların, sıralı dosyalardan
farkını açıklayalım. Rastgele erişimli dosyalarda aranılan bir
kayda, indeks numarası verilerek erişilebilir. Fakat sıralı erişimli dosyalarda
ise, bir kayda ulaşabilmek için tüm dosyayı baştan sona kadar taramak gerekir.
Dolayısıyla bir veriye erişmede veya veriyi aramada, sıralı erişimli dosyaların
dezavantajı vardır. Arama işlemi için zaman kaybı olur.
Bu zamana kadar sıralı erişimli dosyalar üzerinde işlem yaptık. Bir dosyayı
okurken dosya sonuna gelip gelmediğini kontrol etmiştik.
Rastgele erişimli dosyalar ile çalışmak için RandomAccessFile sınıfı kullanılır.
Bu sınıf da java.io paketinin altında bulunur.
Bu yöntem ile dosyalar üzerinde işlem yapacaksak yazma ve okuma için ayrı
ayrı sınıflar oluşturmamıza gerek yoktur. Parametre olarak verdiğimiz
farklı modlar ile hangi işlemi yapmak istediğimizi biz söyleyeceğiz. Peki, bu
modlar nelerdir, onlara bakalım.

r: Dosyayı okumak için kullanılır.

rw: Dosyada hem okuma hem de yazma işlemi yapmak için kullanılır.

rws: Okuma ve yazma işlemleri yapılırken bu veriler de diske yazılır.
Rastgele erişimli dosyalar üzerinde işlem yapmak
için RandomAccessFile sınıfını kullanacağız. Bununla hem okuma hem de
yazma işlemleri yapılır.
Bu modları kullanarak örnek yapalım.
//RandomDosyalar.java - 22.04.2014
1
2 import java.io.*;
3
4 public class RandomDosyalar
5 {
6
public static void main(String[] args) throws Exception
7
{
8
File f = new File("C:\\elektroarge\\random.txt");
9
RandomAccessFile islem = new RandomAccessFile(f,
10 "rw");
11
byte veri = islem.readByte();
12
System.out.println((char)veri);
13
14
String satir = islem.readLine();
15
System.out.println(satir);
16
17
islem.seek(f.length()); // imleç dosya sonuna
18 konumlanır
19
islem.seek(0);
// imleç dosya başına konumlanır
20
String satir2 = islem.readLine();
21
System.out.println(satir2);
22
}
23 }
24
Ekran çıktısı:
O
1
kan Bilke - Elektronik Araþtýrma Geliþtirme
2
Platformu
3
Okan Bilke - Elektronik Araþtýrma Geliþtirme
Platformu
1.
random.txt dosyamızı okuma ve yazma modunda açtık.
2.
RandomAccessFile sınıfının bir metodu olan readByte() ile dosyadan
bir karakter okuduk ve bytetipindeki değişkene attık.
3.
Alt satırda ise bunu tekrar char tipine cast ettik. Çünkü okunan
veri byte tipindedir.
4.
Görüldüğü gibi dosyadaki ilk harf olan J harfini ekrana yazdı.
5.
Daha sonra yine RandomAccessFile sınıfının bir metodu
olan readLine() metodu ile satırın tamamını okuduk. Tabi
bunu islem nesnemiz üzerinden yapıyoruz. Fakat burada O harfimizi
yazmadığını gördük. Bunun sebebi; bir önceki satırda bir karakter
aldık ve imlecimiz O harfinin arkasına konumlandı, yani ilerledi.
6.
islem.seek(f.length()); ile dosyanın sonuna konumlandık. Bunu, nasıl
yapıldığını göstermek için denedik.
7.
islem.seek(0); ile tekrar dosyanın başına konumlandık.
8.
Son satırda ise tüm satırı yazdırmak istediğimizde J harfinin de
yazıldığını gördük.
Bir başka örnek yapalım:
//RandomDosyalar2.java - 22.04.2014
1
2
import java.io.*;
3
4
public class RandomDosyalar2
5
{
6
public static void main(String[] args) throws Exception
7
{
8
File f = new File("C:\\elektroarge\\random.txt");
9
RandomAccessFile islem = new RandomAccessFile(f,
10
"rw");
11
islem.seek(0);
12
byte veriler[] = "Onur".getBytes();
13
islem.write(veriler);
14
}
15
}
16
17
Program çalışmadan önce dosyamızın ilk hali yukarıdaki gibidir. Program
çalıştıktan sonra ise aşağıdaki gibi olur. "Okan" yazısının yerine "Onur" yazısı
gelmiştir.
seek() metodu, imleci belirtilen indise konumlandırır ve işlemler bu indisin
olduğu yerden itibaren yapılmaya başlanır. İmleci "Okan" yazısının başına yani
0. indise koyduk. Arama işlemleri için de bu şekilde bir mantık uygulanır.
Bu örnekte modumuzu rw değil de r yapsaydık hata ile karşılaşacaktık. Çünkü
biz dosyayı hem okuduk içerisine konumladık hem de dosyaya bir şeyler
yazdık.
Dosyaya veri yazma ile ilgili bir örnek daha verelim.
1
//RandomDosyalar3.java - 22.04.2014
2
3
import java.io.*;
4
5
public class RandomDosyalar3
6
{
7
public static void main(String[] args) throws Exception
8
{
9
File f = new File("C:\\elektroarge\\random.txt");
10
11
RandomAccessFile islem = new RandomAccessFile(f,
12 "rw");
13
islem.writeBytes("Java, çok güçlü bir dildir");
14
islem.close();
15
}
16 }
writeBytes() metodu ile String bir veri yazabiliriz.
islem.getFilePointer(); metodu ile de o anki pointer konumunu döndürür.
Yukarıdaki örnek üzerinde deneseydik 26 sayısını döndürecekti. Aşağıdaki
örneği inceleyelim.
//RandomDosyalar4.java - 22.04.2014
1
2
import java.io.*;
3
4
public class RandomDosyalar4
5
{
6
public static void main(String[] args) throws Exception
7
{
8
File f = new File("C:\\elektroarge\\random.txt");
9
RandomAccessFile islem = new RandomAccessFile(f,
10
"rw");
11
islem.writeBytes("Java, çok güçlü bir dildir");
12
System.out.println(islem.getFilePointer());
13
islem.writeInt(3333);
14
System.out.println(islem.getFilePointer());
15
islem.writeDouble(256.6);
16
System.out.println(islem.getFilePointer());
17
}
18
}
19
20
Ekran çıktısı:
1
26
2
30
3
38
İlk olarak 26 sayısını döndürür. Daha sonra bir int değeri ekledik. Bu int değeri
4 byte yer kapladığı için pointer 4 basamak daha ilerledi. Son olarak double bir
veri ekledik. Bu da 8 byte olduğu için 8 basamak ilerledi.
Ders 125 - Object Serialization (Nesne Serileştirme)
Serileştirme işlemi, bir nesneyi bir yerden başka bir yere taşımak, nesneyi
depolayıp istenildiğini zaman tekrar elde etmek için kullanılır.
Java'nın artılarından birisi de bu serileştirme işlemidir. Serileştirme işlemini
kullanarak bir nesnenin anlık olarak tuttuğu bilgiler bir yere kaydedilir ve
istenildiği zaman aynı şekilde bu bilgiler elde edilir.
Bu şekilde nesneyi diske kaydedip istediğimiz yerde kullanabiliriz. Serileştirme
işlemi yapılırken nesne bilgileri, byte olarak diske kaydedilir. Bu nesneye
tekrar ulaşılmak istendiğinde bu byte veriler kullanılarak nesne tekrar elde
edilir.
Serileştirme işlemi nesneleri ağ üzerinden taşımak için kullanılır. Bu nesnenin
her yerde çalışmasını, bubyte olarak saklanmış veriler sağlar. Bu byte veriler,
ağ üzerinden başka bir bilgisayara gönderilir ve o bilgisayarda bu byte veriler
tekrar nesneye dönüştürülür.
Java'nın platform bağımsızlığının bir başka göstergesi de
bu Serileştirme kavramıdır. Bir nesne Windowsortamından Linux ortamına
taşınabilir. Tabi yine bunu JVM sağlar. Nesneler byte olarak kaydedildiği için
başka bir ortamda da bu byte veriler okunarak o nesne tekrar elde edilir.
Bu şekilde bir nesnenin byte olarak saklanmasına Serialization,
bu byte veriden tekrar nesne oluşturulmasına da DeSerialization denir.
SERIALIZABLE ARAYÜZÜ
Java'da serileştirme yapabilmek için ilk
yöntem Serializable arayüzünü kullanmaktır. Bunun için
sınıfımızın, Serializable arayüzünü gerçekleşmesi gerekir. Yani o
sınıfımız, java.io.Serializable arayüzünü kullanmış olmalıdır.
Bu yöntem ile bir örnek yapalım.
İlk olarak Calisan adında bir sınıf oluşturuyoruz ve aşağıdaki kodları yazıyoruz.
1 //Calisan.java - 22.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package Serializable;
import java.io.*;
public class Calisan implements Serializable // implement
işlemi
{
private String ad; // değişkenlerimizi tanımladık
private String soyad;
public Calisan(String ad, String soyad) // yapıcımız
{
this.ad = ad;
this.soyad = soyad;
}
public String getAd() // getter metodları
{
return ad;
}
public String getSoyad()
{
return soyad;
}
}
Calisan sınıfını, Serializable sınıfından implement ediyoruz. Bu yöntem ile
serileştirme işlemi için bunu yapmamız gerekir. Daha
sonra ad ve soyad değişkenleri tanımlıyoruz. Yapıcımızı, getter metotları
yazıyoruz.
Şimdi ise serileştirme için Serialization adlı bir sınıf oluşturalım ve aşağıdaki
kodları yazalım.
1 //Serialization.java - 22.04.2014
2
3 package Serializable;
4 import java.io.*;
5
6 public class Serialization
7 {
8
public static void main (String[] args)
9
{
10
Calisan isci = new Calisan("Okan",
11 "Bilke");
12
ObjectOutputStream o1 = null;
13
FileOutputStream f1 = null;
14
try
15
{
16
f1 = new
17 FileOutputStream("bilgiler.txt");
18
// dosya yolu verildi
19
o1 = new ObjectOutputStream(f1);
20
o1.writeObject(isci);
21
// isci nesnesi dosyaya yazdırıldı
22
}
23
catch (IOException i)
24
{
25
i.printStackTrace();
26
}
27
finally
28
{
29
try
30
{
31
if (o1 != null)
32
o1.close();
33
if (f1 != null)
34
f1.close();
35
} catch (IOException ex)
36
{
37
ex.printStackTrace();
38
}
39
}
40
}
41 }
Burada ilk olarak isci nesnesi oluşturuyoruz ve ilk değerlerini gönderiyoruz.
Sonra o1 ve f1 nesnelerini oluşturuyoruz. İlk değer olarak null veriyoruz, yoksa
hata verecektir. Dosya işlemlerini try içerisinde yapıyoruz. f1 nesnesine dosya
adımızı veriyoruz. Bu dosya, doğrudan projenin olduğu klasörde
oluşacaktır.o1 nesnesinin olduğu sınıfın yapıcısına da f1'i parametre olarak
veriyoruz. Bu ObjectOutputStream sınıfı, nesne yazdırmak için kullanılır.
Daha sonra isci nesnesini dosyaya yazdırıyoruz. Son olarak da dosya kapatma
işlemlerini gerçekleştirdik.
Bu işlemler ile nesnemizi byte olarak dosyaya kaydettik. Daha
sonra Deserialization işlemi ile bu nesnenin bilgilerini aynen elde edeceğiz.
Şimdi de Deserialization işlemi için Deserialization sınıfı oluşturalım ve
aşağıdaki kodları yazalım.
1 //Deserialization.java - 22.04.2014
2
3 package Serializable;
4 import java.io.*;
5
6 public class Deserialization
7 {
8
public static void main (String[] args)
9
{
10
FileInputStream f2 = null;
11
ObjectInputStream o2 = null;
12
try
13
{
14
f2 = new FileInputStream("bilgiler.txt");
15
o2 = new ObjectInputStream(f2);
16
Calisan isci = (Calisan) o2.readObject(); // cast işlemi
17
System.out.println("Elde edilen nesne:" + isci.getAd() + "
18 " + isci.getSoyad());
19
}
20
catch (IOException e)
21
{
22
e.printStackTrace();
23
}
24
catch (ClassNotFoundException e)
25
{
26
e.printStackTrace();
27
}
28
finally
29
{
30
try
31
{
32
if (o2 != null)
33
o2.close();
34
if (f2 != null)
35
f2.close();
36
} catch (IOException e)
37
{
38
e.printStackTrace();
39
}
40
}
41
}
42 }
43
Ekran çıktısı:
Elde edilen nesne: Okan
1
Bilke
Deserialization işlemi için başlangıçta yaptığımız adımlar aynıdır. Fakat
sınıflarımız Input olarak değiştirildi. Çünkü bir okuma işlemi
yapacağız. o2 nesnesi üzerinden readObject metodunu kullanarak nesnemizi
dosyadan okuyoruz. Fakat bunu Calisan sınıfına cast etmemiz gerekiyor.
Okunan nesnenin sınıfını belli etmek için bunu yapıyoruz. Daha sonra
bunu isci adlı nesneye atıyoruz ve bu nesne üzerinden adı ve soyadı
getiren getAd() ve getSoyad() metotlarını çağırıyoruz. İşlem sonunda da
dosyaları kapatıyoruz.
EXTERNALIZABLE ARAYÜZÜ
Serializablearayüzünü kullanarak nesnelerini nasıl dosyaya aktarırız ve daha
sonra tekrar aynı şekilde bu nesneyi elde ederiz, bunu gördük. Şimdi ise
serileştirme için 2. yöntem olan Externalizable arayüzünü anlatacağız.
Bu şekilde serileştirme yapabilmek için
sınıfımızı Externalizable arayüzünden implement etmemiz gerekir.
Peki, hangi durumda bu 2. yöntemi kullanacağız. Eğer serileştirmek istediğimiz
nesnenin her özelliğini serileştirmek istemiyorsak, bu yöntemi kullanmalıyız.
Bir önceki yöntemde nesnemizin her alanını serileştirdik.
1. yöntemde readObject() metodu ile nesnemizin tamamını okuduk. Fakat bu
yöntemde nesnemizin okunmasını istediğimiz
yerlerini, readExternal() metodumuza parametre olarak
göndereceğiz.writeExternal() ile de serileştirmek istediğimiz yerleri, bu
metoda parametre olarak veririz. Tatbikî bu iki metot birbirinin tersi işleri
yapıyor.
Peki, bu yöntem bize ne avantaj sağlar? Başkalarının bilmemesi gereken yerler,
serileştirme işlemine tabi tutulmazlar. Çünkü bu alanların tersi işlem yapılarak
tekrar elde edilmesi sakıncalıdır. Bu yüzden 1. yöntem ile serileştirme
yapıldığında bu gizli alanlar da serileştirme işlemine girer. Bu tür şeyler için 2.
yöntem kullanılır. Yani
sınıfımızı, Externalizable arayüzünden implement etmek gerekir.
Bir örnek vererek konumuzu kapatalım.
Calisan adlı bir sınıf oluşturalım.
1
//Calisan.java - 22.04.2014
2
3
package Externalizable;
4
import java.io.*;
5
6
public class Calisan implements Externalizable
7
{
8
private String ad, soyad;
9
private int maas;
10
// parametreli yapıcı
11
12
public Calisan(String ad, String soyad, int maas)
13
{
14
this.ad = ad;
15
this.soyad = soyad;
16
this.maas = maas;
17
}
18
19
public Calisan() // varsayılan yapıcı
20
{
21
}
22
23
public String getAd()
24
{
25
return ad;
26
}
27
public String getSoyad()
28
{
29
return soyad;
30
}
31
public int getMaas()
32
{
33
return this.maas;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
}
// serileştirme yapan writeExternal metodu
public void writeExternal(ObjectOutput yazdir)
{
try
{
yazdir.writeObject(this.ad);
yazdir.writeObject(this.soyad);
}
catch (Exception e)
{
System.out.println("Hata oluştu");
}
}
// serileştirilen nesneyi geri okuyan readExternal
metodu
public void readExternal(ObjectInput oku)
{
try
{
this.ad = (String)oku.readObject();
this.soyad = (String)oku.readObject();
}
catch (Exception e)
{
System.out.println("Hata oluştu");
}
}
}
Şimdi buradaki kodlarımızı açıklayalım.
1.
Bir çalışan için 3 değişken tanımladık. Maaş verisini gizlemek
istiyoruz. Bunun için Externalizablearayüzünü kullanmamız gerekir.
2.
Alınan değerleri, değişkenlerimize atayacak olan parametreli yapıcıyı
yazıyoruz.
3.
Varsayılan yapıcıyı yazıyoruz. Bu 2. yöntemi kullanırsak, varsayılan
yapıcı yazmamız gerekir.
4.
Değerleri döndüren getter metotlarını yazıyoruz.
5.
Serileştirme işlemini yapacak olan writeExternal() metodunu
yazıyoruz. İşlemlerimizi try catch içerisinde yapıyoruz. Çünkü dosya
işlemleri try ifadesi içerisinde yazılmalıdır. Serileştirme yaparken
maaşın bilinmesini istemediğimiz için writeObject() metodumuza bu
değeri göndermedik. writeExternal()metoduna parametre
olarak yazdir nesnesini veriyoruz. Çünkü verilerimiz bu nesnede saklı.
6.
Serileştirilen nesneyi geri getiren readExternal() metodu
ise, oku nesnesini parametre olarak alıyor. Buoku nesnesinin tipi
de ObjectInput sınıfıdır. Bu oku nesnesi
üzerinden readObject() metodunu çağırıyoruz
ve String tipine cast ediyoruz.
Çünkü ad ve soyad değişkenlerimiz String tipindedir. Eğer
buradaki try içerisinde this.maas=(int)oku.readInt(); metodumu
yazsaydık hata alacaktık. Çünkü maaşımızı geri getiremeyiz.
7.
Oluşabilecek hatalara karşı catch içerisinde mesajımızı yazdırdık.
Buradaki oku ve yazdir nesnelerini diğer sınıflarda oluşturacağız.
Şimdi ise serileştirme işlemini yapacak olan Serialization sınıfını yazıyoruz.
1 //Serialization.java - 22.04.2014
2
3 package Externalizable;
4 import java.io.*;
5
6 public class Serialization
7 {
8
public static void main(String[] args)
9
{
10
try
11
{
12
Calisan calisan1 = new Calisan("Okan", "Bilke", 1500);
13
FileOutputStream f1 = new
14 FileOutputStream("C:\\elektroarge\\calisan.txt");
15
ObjectOutputStream o1 = new ObjectOutputStream(f1);
16
o1.writeObject(calisan1);
17
o1.close();
18
}
19
catch (Exception e)
20
{
21
e.printStackTrace();
22
}
23
}
24 }
25
1.
Bu sınıfımıza calisan1 nesnesine ad, soyad, maaş değerlerini
giriyoruz. Bu parametreler, az önce anlattığımız sınıfın yapıcısına
gider ve değerleri ilgili değişkenlere atanır.
2.
Yazdırma işlemi yapacağımız
için FileOutputStream ObjectOutputStream sınıfını kullanıyoruz
ve gerekli parametreleri verdik.
3.
o1 nesnesi üzerinden writeObject() metodunu çağırdık ve nesnemizi
gönderdik. Bu metot, serileştirme işlemini yapan metoddur.
4.
Son olarak dosyamızı kapattık.
Şimdi de son olarak Deserialization işlemini yapan Deserialization sınıfını
yazıyoruz.
1 //Deserialization.java - 22.04.2014
2
3 package Externalizable;
4 import java.io.*;
5
6 public class Deserialization
7 {
8
public static void main(String[] args)
9
{
10
try
11
{
12
Calisan calisan1;
13
FileInputStream f2 = new
14 FileInputStream("C:\\elektroarge\\calisan.txt");
15
ObjectInputStream oku = new ObjectInputStream(f2);
16
calisan1 = (Calisan)oku.readObject();
17
System.out.println(calisan1.getAd());
18
System.out.println(calisan1.getSoyad());
19
System.out.println(calisan1.getMaas());
20
oku.close();
21
}
22
catch (Exception e)
23
{
24
e.printStackTrace();
25
}
26
}
27 }
28
1.
Calisan sınıfındaki verilerle işlem yapabilmek için calisan1 nesnesi
oluşturduk.
2.
Okuma işlemi yapacağımız için Input türündeki sınıflardan nesneler
oluşturduk ve gerekli parametreleri verdik.
3.
oku nesnesi üzerinden readObject() metodunu çağırdık ve yine nesne
olarak kaydetmek istediğimiz için Calisan sınıfına cast ettik.
Bu readObject() metodu, ObjectOutputStream sınıfına ait bir
metottur.
4.
Daha sonra bu calisan1 nesnesi
üzerinden getAd(), getSoyad, getMaas metotlarını çağırdık.
5. Son olarak dosyamızı kapattık.
Okan
Bilke
0
1
2
3
Deserialization sınıfını çalıştırdığımızda yukarıdaki çıktıyı elde edeceğiz.
Maaş değişkeni int tipinde olduğu için onun varsayılan değerini verdi. Yani
maaşı serileştirmedik o yüzden değerini elde edemedik. Fakat 1500değerini
vermiştik.
Istisnalar:
! implement edeceğimiz sınıf, değişkenlerimizin olduğu sınıftır. Bu
sınıf, Externalizable veya Serializablesınıfından implement edilmelidir.
Istisnalar:
!
Externalizable arayüzünü kullanarak bir Serileştirme
yaptığımızda, Serializable arayüzü kullanmaya göredaha az disk
alanı harcanacaktır. Bu da Externalizable arayüzü kullanmanın başka
bir avantajıdır.
TRANSIENT ANAHTAR KELİMESİ
transient anahtar kelimesi, bir önceki konuda anlattığımız gibi serileştirilmesini
istemediğimiz veriler için kulanılır.
Bu anahtar kelimesini kullanacaksak
sınıfımızı Serializable arayüzünden implement etmemiz gerekir.
Çünkü Externalizable arayüzünü kullandığımızda zaten istemediğimiz verileri
serileştirmiyorduk.
Bu şekilde serileşmesini istemediğimiz verilerin başına transient anahtar
kelimesini getirdiğimizde, o veri serileştirilemeyecek ve dolayısıyla elde etmek
istediğimizde sonuç alamayacağız.
Diyelim ki kişinin adına erişilmesin istiyoruz. Calisan sınıfında ad değişenini
tanımlarken şu şekilde tanımlamalıyız.
private transient String
1
ad;
Bunun dışında Serializable arayüzünü kullanma, yani 1. yöntemdeki her şey ile
aynıdır. Yalnızca serileştirilmesini istediğimiz yerlerin başına bu kelime yazılır.
Bu yöntem, Externalizable yönteminin alternatifidir. Daha çok kod yazmak
yerine tek kelime ile aynı işi yapabiliriz.
Istisnalar:
!
3 yöntemde de bir ortak nokta vardır. Serileştirme işlemlerinde hangi
sıra ile verileri serileştirdiysek, elde ederken de o sıra ile elde edilir.
Istisnalar:
!
Serileştirilecek elemanların olduğu sınıfın içerisinde, başka bir sınıfa
ait nesne varsa, o nesnenin ait olduğu sınıfın da serileştirilebilir bir
sınıf olması gerekir.
Ders 126 - Koleksiyonlara Giriş
Yazılım geliştirirken bazen tek bir değişken içerisinde birden fazla eleman
tutmak isteyebiliriz. Bu gibi durumlarda Java'nın Collection sınıfını kullanmak
daha doğru olacaktır. Collection sınıfı ArrayList, bağlı liste yapısı
(LinkedList) ve HashSet gibi veri yapılarını içerir.
Genellikle Collection sınıfları veri depolamak, depolanan veriyi çekmek,
veriyi işlemek ve depolanan veriler içerisinde veri aramak gibi işlemler için
kullanılırlar. Koleksiyonlar sıralı veya sırasız şekilde olabilirler. Java
koleksiyonlarının avantaj ve dezavantajlarını şöyle sıralayabiliriz.
JAVA KOLEKSİYONLARININ AVANTAJLARI

Verileri bir araya toplamamızı ve veriler üzerinde işlem yapmamızı
kolaylaştırır.

Yazılımcı, koleksiyon sınıfı içerisindeki algoritmaları kullanarak, yeni
algoritma yazmak zorunda kalmaz. Bu da yazılımın daha kolay
anlaşılmasını ve tekrar kullanılmasını sağlar.

Yazılımcıya uygulamanın performansını artıran kullanışlı algoritma ve
veri yapıları sağlar.

Belli bir boyutları yoktur. İçerisine veri ekleyip çıkardıkça boyutları
değişir. Yani yazılımcının önceden koleksiyonu boyutlandırmasına
gerek yoktur.
JAVA KOLEKSİYONLARININ DEZAVANTAJLARI

Koleksiyonlarda aynı değişkenler gibi veri tipleri vardır. Yani veri
eklerken koleksiyonun veri tipine uygun verileri ekleyebiliriz.

Derleme anında veri tipini denetimi yapılmaz.
Ders 127 - Collection Arayüzü
Collection arayüzü, koleksiyon arabirimlerinin hiyerarşik olarak en tepesinde
bulunan birimdir. Java.Utilpaketi içerisinde bulunan bu arayüz, bize birkaç
arayüz ve bunlar altında bulunan sınıfları sunar. Aşağıdaki diyagram bize
koleksiyon hiyerarşisini gösteriyor.

Collection: Koleksiyon arayüzlerinin hiyerarşik olarak en tepesinde
bulunan, en genel koleksiyon arayüz sınıfıdır.
o
List: Liste yapısını örnek alan koleksiyon tipidir. İçerisinde
bir elemandan birden fazla bulundurmaya izin verir.
Elemanları sıralı bir biçimde tutar.
o
Queue: Kuyruk yapısını benimseyen koleksiyon tipidir. Liste
tipinden türetilmesine karşın liste tipinin ana özelliği olan
indis değerleriyle işlem yapmamasıyla liste türünden ayrılır.
o
Set: İçerisinde sakladığı elemanlar sıralı bir biçimde
tutulmaz. Ayrıca bu koleksiyon tipi içerisinde kopya eleman
bulundurmaz. Yani her elemandan sadece bir tane
bulunabilir.

SortedSet: Verileri sıralı bir biçimde
tutar. Set tipinde de olduğu gibi bu tip kopya eleman
bulundurmaya izin vermez.

Map: Elemanlarla bunlara karşılık verilen anahtar değerleri eşleştiren
arayüzdür. Tekrarlı anahtar değerleri içermez. Map arayüzü,
koleksiyon arayüzü ile benzerlik gösterir. Ancak aralarındaki temel
fark; map arayüzünün elemanlarının her birinin bir anahtar değer ile
eşleştirilerek saklanmasıdır.
o
Sorted Map: Map arayüzünün özelliklerini taşır, ancak bu
arayüzde anahtar değerleri artan bir sırada saklanır.
Koleksiyon sınıfları ortak bir takım metotları kullanır. Metotlar bazı koleksiyon
sınıflarında farklılık göstermesine karşın genel olarak aynıdır. Koleksiyon
sınıflarının ayrıntılarına geçmeden bu metotları ve metotlardan bazılarının
görevlerini bilmek fayda sağlayacaktır.

add: Koleksiyon nesnesine referans verilen elemanı ekler.

remove: Koleksiyon nesnesinden referans verilen elemanı siler.

size: Koleksiyon nesnesindeki eleman sayısını verir.

isEmpty: Koleksiyon nesnesinin boş olup olmadığını kontrol eder.

contains: Koleksiyon nesnesi içerisinde referans olarak belirtilen
elemanı arar.

iterator: Koleksiyon nesnesini iterasyon nesnesine referans olarak
göndermeye yarar.
Ders 128 - Iterator
Koleksiyon arayüzünün detaylarına geçmeden önce iterator arayüzünü
öğrenmek faydalı olacaktır.Iterator() metodu koleksiyon
nesnelerini yinelememizi sağlar. Iterator arayüzü metotları; koleksiyon nesnesi
altındaki elemanlar arasında başlangıçtan sonuna kadar tek tek geçiş
yapmamızı, elemanları güvenle silmemizi sağlar. Iterator arayüzünün
metotlarını şöyle sıralayabiliriz:

hasNext: Koleksiyon nesnesinin bir sonraki elemanının var olup
olmadığını kontrol eder. Koleksiyon nesnesinin bir sonraki elemanı
mevcut ise true; mevcut değil ise false değer döndürür.

next: Koleksiyon nesnesini bir sonraki elemana ulaşması için
iterasyon yapar ve iterasyon nesnesinin gösterdiği elemanı geri
döndürür.

remove: Koleksiyon nesnesi üzerindeki iterasyon nesnesinin
gösterdiği elemanı siler.
Iterator arayüzün metotlarını bir örnekte kullanarak açıklayalım.
1
//Iterator.java - 23.04.2014
2
3
import java.util.Collection;
4
5
public class Iterator
6
{
7
public static void main(String[] args)
8
{
9
Collection c = new Collection();
10
Iterator i = c.iterator();
11
12
while (i.hasNext())
13
{
14
System.out.println("Sıradaki eleman : " +
15
i.next());
16
i.remove();
17
}
18
}
19
}
20
Yukarıdaki
örnekte önce bir koleksiyon nesnesi tanımlayıp, daha sonra bu koleksiyon
nesnesi için tanımladığımız iterator nesnesini çağırdık. i.hasNext() metoduyla
koleksiyon nesnesinin bir sonraki elemanı mevcut ise, döngü çalışıyor. Daha
sonraki satırda i.next() metodu ile iterator nesnesinin koleksiyon üzerinde
gösterdiği elemanı ekrana yazdırıyoruz. En son satırda ise i.remove() metodu
ile iterator nesnesinin koleksiyon üzerinde gösterdiği elemanı siliyoruz.
Ders 129 - Set (Kümeler)
Set arayüzü, collection arayüzünü miras alır. Bu sınıfı matematikteki kümelere
benzetebiliriz. Matematikte elemanların kümeler içerisinde sıralı bir şekilde
tutulma zorunluluğu yoktur ve bir elemandan bir küme içerisinde yalnızca bir
tane bulunabilir. Bu sınıf içinde durum aynen böyledir. Elemanlar sıralı bir
biçimde tutulması gerekiyorsa, SortedSet alt sınıfının
öğesi TreeSet kullanılabilir. Set arayüzünün öğesi HashSet'dir.
HASHSET
HashSet koleksiyonu, Set koleksiyon tipinin bir örneğidir. Bu koleksiyon tipi
yukarıda da bahsedildiği gibi tam olarak kümelere benzer. Elemanların sıralı
olması şartı yoktur ve her elemandan bir küme içerisinde yalnız bir tane
bulunabilir. HashSet koleksiyonunun bir diğer özelliği de erişim
sırasının belirsiz olmasıdır.HashSet koleksiyonunun kullanımına bir örnek
vererek bu koleksiyonu daha iyi anlamaya çalışalım.
1
//SetOrnek.java - 23.04.2014
2
3
import java.util.*;
4
5
public class SetOrnek
6
{
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static void main(String[] args)
{
// HashSet nesnesi tanımladık.
HashSet hSet = new HashSet();
// öğeleri HashSet koleksiyonuna ekliyoruz
hSet.add("Okan");
hSet.add("Onur");
hSet.add("Göksu");
hSet.add("Bilke");
// HashSet nesnesini iterator öğesine bağladık
Iterator i = hSet.iterator();
while(i.hasNext())
{
System.out.println("Küme elemanı : " +
i.next());
}
}
}
Ekran çıktısı:
1
Küme elemanı : Onur
2
Küme elemanı : Göksu
3
Küme elemanı : Bilke
4
Küme elemanı : Okan
Örnekte de görüldüğü gibi öğeler HashSet üzerinde sırasız bir şekilde
saklanıyor. Öğelere erişim kısmında ise belirsiz bir erişim sırası var.
Set koleksiyonlarının bir diğer özelliğinden yukarıda
bahsetmiştik. Set koleksiyonları tekrarlı eleman içermezler. Bu özelliğe de bir
örnek vererek açıklayalım.
1
//SetOrnek2.java - 23.04.2014
2
3
import java.util.*;
4
5
public class SetOrnek2
6
{
7
public static void main(String[] args)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
// HashSet nesnesi tanımladık.
HashSet hSet = new HashSet();
// öğeleri HashSet koleksiyonuna ekliyoruz
hSet.add("Okan");
hSet.add("Onur");
hSet.add("Göksu");
hSet.add("Bilke");
hSet.add("Okan");
hSet.remove("Göksu");
// HashSet nesnesini iterator öğesine bağladık
Iterator i = hSet.iterator();
while(i.hasNext())
{
System.out.println("Küme elemanı : " +
i.next());
}
}
}
Ekran çıktısı:
Küme elemanı :
Onur
1
Küme elemanı :
2
Bilke
3
Küme elemanı :
Okan
Öncelikle remove() metodunun kullanımına göz atalım. remove() metoduyla
belirttiğimiz elemanHashSet koleksiyon öğesi içerisinde bulunuyorsa silinir.
Eleman HashSet koleksiyon öğesinde bulunmuyorsa,remove() metodu
geri false değeri döndürür. HashSet koleksiyonumuza verileri eklerken "Okan"
öğesini iki kere ekledik ama program bize örnekte de olduğu gibi sonuçta
"Okan" öğesini bir kere verdi. "Okan" öğesini iki kere
eklememiz HashSet koleksiyon öğelerine erişim sırasını değiştirmedi. Ayrıca
program derleme anında hata vermez. Peki, iki kere eklenilen elemanı
bulmamız mümkün değil midir? Bu soruya şöyle cevap verelim. Koleksiyon
sınıflarının ortak kullanıldığı add() metodu eklenilen elemanın koleksiyon
içerisinde var olup olmadığını kontrol eder. Eğer eklemek istenilen eleman
koleksiyon içerisinde yoksa geriye true; zaten var isefalse değer döndürür. Bu
durumu daha iyi kavrayabilmek için yine kısa bir örnekle açıklayalım.
//SetOrnek3.java - 23.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.util.*;
public class SetOrnek3
{
public static void main(String[] args)
{
// kopya eleman bulunduran dizi oluşturuldu
String[] a = {"Okan", "Onur", "Göksu", "Bilke",
"Okan"};
// kopya eleman kontrol değerini tutacak değer
boolean b;
// HashSet nesnesi oluşturduk
HashSet hSet = new HashSet();
// a dizisinin her elemanı için for döngüsü çalışır
for(String s : a)
{
// hSet öğesine s alanının içindeki değeri
kopyaladık
b = hSet.add(s);
if(!b)
System.out.println("Kopya eleman bulundu : "
+ s);
}
Iterator i = hSet.iterator();
while(i.hasNext())
{
System.out.println("Küme elemanı : " + i.next());
}
}
}
Ekran çıktısı:
1
2
3
4
5
Kopya eleman bulundu :
Okan
Küme elemanı : Onur
Küme elemanı : Göksu
Küme elemanı : Bilke
Küme elemanı : Okan
Örnekte kopya eleman bulunduran bir dizi tanımladık. Daha sonra bu dizinin
elemanlarını sıra ile HashSetkoleksiyon öğesine kopyaladık. Burada dikkat
edilmesi gereken nokta add() metodu, yukarıda da bahsettiğim gibi eleman
zaten mevcut ise, false değeri döndürecektir. Örnekte if kontrolü ile bu kopya
değeri bulduktan sonra ekrana yazdırıyoruz.
Kısacası; HashSet koleksiyon öğesini, sıranın önemsiz olduğu ve toplu veri
depolamak istediğiniz uygulamalarınızda kullanabilirsiniz.
LINKEDHASHSET
LinkedHashSet, HashSet koleksiyon öğesine genel olarak benzemesine karşın
bir özelliğiyle HashSetöğesinden ayrılır. HashSet koleksiyon öğesinde verilere
erişim sırası belirsizdi. Bu koleksiyon öğesinde ise öğeler birbirine çift
yönlü bağlıdır. LinkedHashSet öğelerinin erişim sırasını, aşağıdaki örnek
üzerinden daha iyi görebiliriz.
1
//LinkedHashSetOrnek.java - 23.04.2014
2
3
import java.util.*;
4
5
public class LinkedHashSetOrnek
6
{
7
public static void main(String[] args)
8
{
9
// LinkedHashSet koleksiyon öğesini oluşturduk
10
LinkedHashSet linkedHashSet = new
11
LinkedHashSet();
12
13
// elemanları koleksiyonumuza ekledik
14
linkedHashSet.add("Okan");
15
linkedHashSet.add("Onur");
16
linkedHashSet.add("Göksu");
17
linkedHashSet.add("Bilke");
18
linkedHashSet.add("Okan");
19
20
// koleksiyonumuza iterator öğemize bağladık
21
22
23
24
25
26
27
28
29
Iterator i = linkedHashSet.iterator();
while(i.hasNext())
{
System.out.println("Koleksiyon öğeleri : " +
i.next());
}
}
}
Ekran çıktısı:
Koleksiyon öğeleri :
Okan
1
Koleksiyon öğeleri :
2
Onur
3
Koleksiyon öğeleri :
4
Göksu
Koleksiyon öğeleri :
Bilke
Örnekte de görüldüğü gibi, LinkedHashSet koleksiyon öğesi elemanları giriş
sırasına göre birbirine çift yönlü bağlar. Elemanlar bağlı olmasına karşın yine
de birbirleri arasında düzgün şekilde bir sıra bulunmuyor. Yani, elemanlar artan
sırada sıralı değil, giriş sırasına göre sıralıdır. LinkedHastSet koleksiyon
öğesi HashSetöğesinde de olduğu gibi kopya eleman bulundurmaz.
SORTED SET
SortedSet koleksiyon arayüzü, set koleksiyon arayüzünün alt
arayüzüdür. Set koleksiyon arayüzü ile genel olarak aynı özelliklere sahip
olmasına karşın elemanları sıralı tutmasıyla HashSet koleksiyon öğesinden
ayrılır. Bu arayüzün kullanılan öğesi TreeSet'dir.
TREESET
TreeSet öğesi yukarıda da bahsedildiği gibi SortedSet arayüzünün alt sınıfıdır.
Genel olarak HashSetsınıfı ile aynı metotları kullanılır. Bu koleksiyon
tipinde tip kontrolü yapılır. Dolayısıyla kümeye içerisindeki elemanlardan
farklı tipte bir eleman eklemeye çalışırsak derleme anında
hata verecektir. TreeSet koleksiyon öğesinin genel kullanımını basit bir örnek
üzerinde açıklayalım.
//TreeSetOrnek.java - 23.04.2014
1
2
import java.util.*;
3
4
public class TreeSetOrnek
5
{
6
public static void main(String[] args)
7
{
8
// TreeSet koleksiyon öğesi oluşturduk.
9
TreeSet treeSet = new TreeSet();
10
11
// koleksiyonumuza öğeleri ekledik
12
treeSet.add("İstanbul");
13
treeSet.add("kırklareli");
14
treeSet.add("edirne");
15
treeSet.add("tekirdağ");
16
// tip uyuşmazlığı nedeniyle böyle bir eleman
17
ekleyemeyiz.
18
// treeSet.add(1);
19
20
// treeSet koleksiyon öğesini i iterator nesnesine
21
bağladık.
22
Iterator i = treeSet.iterator();
23
24
while(i.hasNext())
25
{
26
System.out.println(i.next());
27
}
28
}
29
}
30
Ekran çıktısı:
1
edirne
2
kırklareli
3
tekirdağ
4
İstanbul
Yukarıdaki örnekte önce bir TreeSet oluşturduk. Daha sonra verilerimizi
koleksiyon öğemize ekleyip öğeleri tek tek ekranda gösterdik. Örnekte dikkat
edilmesi gereken nokta elemanların sırasıdır. Elemanları karışık sırada
eklememize karşın ekran çıktısında sıralı bir şekilde
alıyoruz. TreeSet koleksiyon öğesi verileriartan
sırada sıralar. TreeSet öğesi HashSet koleksiyon öğesinden farklı bir takım
metotlar içerir. Bunlardan bazıları ve bu metotların açıklamaları şöyledir:
Koleksiyon öğesinin en küçük elemanını verir.
first() : Object
Koleksiyon öğesinin en büyük elemanını verir.
last() : Object
Koleksiyon öğesindeki toElement'den küçük olan
headSet(Object
öğeleri verir.
toElement) : SortedSet
Koleksiyon öğesinde fromElement öğesinden
subSet (Object
başlayıp toElement öğesine kadar olan elemanları
fromElement, Object
verir. Sonuca ilk eleman dahil, son eleman dahil
toElement) : SortedSet
değildir.
Koleksiyon
tailSet (Object
öğesindeki fromElement ve fromElement'den
fromElement) :
sonraki elemanları verir.
SortedSet
Bu metotları daha iyi anlayabilmek için örnek üzerinde açıklayalım.
1 //TreeSetOrnek2.java - 23.04.2014
2
3 import java.util.*;
4
5 public class TreeSetOrnek2
6 {
7
public static void main(String[] args)
8
{
9
// TreeSet koleksiyon öğesini oluşturduk
10
TreeSet treeSet = new TreeSet();
11
12
// Koleksiyonumuza öğeleri ekledik
13
treeSet.add(1);
14
treeSet.add(7);
15
treeSet.add(13);
16
treeSet.add(6);
17
treeSet.add(10);
18
19
System.out.println("TreeSet koleksiyonunun öğeleri : ");
20
System.out.println(treeSet);
21
System.out.println("Koleksiyonun ilk öğesi : " +
22 treeSet.first());
23
System.out.println("Koleksiyonun son öğesi : " +
24 treeSet.last());
25
System.out.print("Koleksiyondaki 7 den küçük elemanlar :
26 ");
27
System.out.println(treeSet.headSet(7));
28
System.out.print("Koleksiyondaki 6 ile 13 arasındaki
29 elemanlar : ");
30
System.out.println(treeSet.subSet(6, 13));
31
System.out.print("Koleksiyondaki 7 ve 7 den büyük
32 elemanlar : ");
System.out.println(treeSet.tailSet(7));
}
}
Ekran çıktısı:
TreeSet koleksiyonunun öğeleri :
1
[1, 6, 7, 10, 13]
2
Koleksiyonun ilk öğesi : 1
3
Koleksiyonun son öğesi : 13
4
Koleksiyondaki 7 den küçük elemanlar : [1, 6]
5
Koleksiyondaki 6 ile 13 arasındaki elemanlar : [6,
6
7, 10]
7
Koleksiyondaki 7 ve 7 den büyük elemanlar : [7,
10, 13]
Yukarıdaki örnekte de görüldüğü gibi headSet() metoduna referans olarak
verilen değer sıralamaya dahil olmazken, tailSet() metoduna referans olarak
verilen değer sıralamaya dahil oluyor. Benzer durumsubSet() metodunda da
mevcuttur. subSet() metoduna referans olarak verilen ilk eleman sıralamaya
dahil olur, son eleman sıralamaya dahil olmaz.
Ders İçinde Yazılmış Tüm Programlar ve Kodları Ektedir:
Ders 130 - Liste Yapıları (List)
List koleksiyon arayüzü, verileri bir dizi halinde depolar. Dizilerde olduğu gibi
burada da elemanlarınindis değerleri vardır. Yazılımcı elemanların indis
değerleri ile elemanlara erişebilir ve indis değerleri ile arama yapabilir. Liste
yapılarını dizilerden (Array) ayıran en önemli özellik, liste
yapılarının boyutlarının önceden ayarlanmış olmamasıdır. Dolayısıyla bu
özellikleriyle dizilerden daha kullanışlıdırlar.
Küme yapılarında her elemandan sadece bir tane bulunabiliyordu. Liste
koleksiyon öğeleri kopya eleman bulundurmaya izin verirler.
LISTITERATOR
Liste yapılarına geçmeden önce ListIterator yapısını öğrenmek bize fayda
sağlayacaktır. Daha önceki konularda küme yapıları için öğeleri yinelemek
için iterator() metodunu kullanmıştık. Liste yapılarında bu metodun yaptığı
görevi ListIterator() metodundan bir takım farklılıkları bulunmaktadır. Liste
yapılarında öğe işlemlerimizi genel olarak indis değerleri üzerinden yaptığımız
için ListIterator() metodu, indis işlemleri için özelleşmiştir. Bazı özel
metotları ve bu metotların açıklamaları şöyledir:

add: Referans olarak verilen elemanı listeye ekler.

hasPrevious: ListIterator() metodu, ters yönde bir elemanı işaret
ediyorsa geriye true değer döndürür. Eleman yoksa geriye false değer
döndürür.

nextIndex: next() metodu tarafından geri döndürülmesi gereken
elemanının indis değerini döndürür. İterasyon yapmaz.

previous: Listeyi sondan başlayarak bir önceki elemana ulaşması için
iterasyon yapar ve iterasyon nesnesinin gösterdiği elemanı geri
döndürür.

previousIndex: previous() metodu tarafından geri döndürülmesi
gereken elemanının indis değerini döndürür. İterasyon yapmaz.

set: next() veya previous() metodu tarafından döndürülen elemanı
referans verilen eleman ile değiştirir.
ARRAYLIST
ArrayList sınıfı, elemanları bir dizi biçimde saklar ve boyutu içine eleman
eklendikçe büyür. ArrayListsınıfının elemanlarına indis değerleriyle erişmek
veya silmek mümkündür.
ArrayList sınıfı dizilerden daha avantajlı olmalarına karşın, bazı durumlarda
dizilerin tercih edilmesi daha uygun olur. Depolanacak veri sayısı belli ve bu
sayı büyük oranlarda değişmiyor ise dizilerin kullanılmasıdaha avantajlıdır.
Veri sayısının belli olmadığı durumlarda ArrayList sınıfı
kullanılabilir. ArrayList sınıfını dizilerden ayıran bir diğer özellik
de, ArrayList sınıfının nesneleri depolayabilir olmasıdır. ArrayList sınıfını
bir örnek üzerinden açıklamaya çalışalım.
1 //ListYapilariOrnek.java - 24.04.2014
2
3 import java.util.ArrayList;
4 import java.util.ListIterator;
5
6 public class ListYapilariOrnek
7 {
8
public static void main(String[] args)
9
{
10
ArrayList arrayList = new ArrayList();
11
12
arrayList.add(1);
13
arrayList.add(2);
14
arrayList.add(3);
15
16
ListIterator i = arrayList.listIterator();
17
18
System.out.println("ArrayList'i baştan sona doğru
19 tarıyoruz...");
20
21
while(i.hasNext())
22
{
23
System.out.print(i.nextIndex() + ". eleman : ");
24
System.out.println(i.next());
25
}
26
System.out.println("ArrayList'i sondan başa doğru
27 tarıyoruz...");
28
29
while(i.hasPrevious())
30
{
31
System.out.print(i.previousIndex() + ". eleman : ");
32
System.out.println(i.previous());
33
}
34
}
35 }
Ekran çıktısı:
ArrayList'i baştan sona doğru
1
tarıyoruz...
2
0. eleman : 1
3
1. eleman : 2
4
2. eleman : 3
5
ArrayList'i sondan başa doğru
6
tarıyoruz...
7
2. eleman : 3
8
1. eleman : 2
0. eleman : 1
Örnekte önce bir ArrayList tanımlayıp elemanlarımızı ArrayList'e ekledik.
Daha sonra ArrayListnesnemizi ListIterator öğesine bağladık.
İlk while döngüsünde ListIterator öğesinin hasNext() metodu ileArrayList'i
baştan sona tarayıp elemanların indis değerlerini ve
elemanları nextIndex() ve next() metotları yardımıyla ekrana yazdırdık.
İkinci while döngüsünde aynı işlemleri ArrayList'i sondan başa doğru
tarayarak yaptık.
Liste yapılarına giriş yaparken, küme yapılarından farklı olarak liste yapılarının
kopya eleman bulundurabileceğini söylemiştik. Peki, ArrayList öğemize farklı
tipte bir eleman eklemeye çalışırsak, hata alır mıyız? Bunu da bir örnek
üzerinden açıklayalım.
1 //ListYapilariOrnek2.java - 24.04.2014
2
3 import java.util.ArrayList;
4 import java.util.ListIterator;
5
6 public class ListYapilariOrnek2
7 {
8
public static void main(String[] args)
9
{
10
ArrayList arrayList = new ArrayList();
11
12
arrayList.add(1);
13
arrayList.add(2);
14
15
16
17
18
19
20
21
22
23 : ");
24
25
26
}
27 }
28
arrayList.add(3);
arrayList.add(1);
arrayList.add("String tipte eleman");
ListIterator i = arrayList.listIterator();
while(i.hasNext())
{
System.out.print(i.nextIndex() + ". eleman
System.out.println(i.next());
}
Ekran çıktısı:
0. eleman : 1
1
1. eleman : 2
2
2. eleman : 3
3
3. eleman : 1
4
4. eleman : String tipte
5
eleman
Örnekte de görüldüğü gibi liste yapıları kopya eleman bulundurmaya izin
veriyor. Farklı tipte bir eleman eklemeye çalıştığımızda ise hata vermedi.
Bunun sebebi; koleksiyon öğelerini tanımlarken tip belirtmediğimiz zaman
elemanlar koleksiyon öğeleri içerisine nesne olarak depolanırlar. Koleksiyon
öğelerini tanımlarken tip belirtmeniz durumunda, farklı tip eleman eklenirken
uygulama hata verecektir.
Son olarak Liste yapılarında kullanılacak genel metotların ArrayList öğesi
üzerinde kullanıldığı bir örnek yaparak, bu sınıfı sonlandıralım.
1 //ListYapilariOrnek3.java - 24.04.2014
2
3 import java.util.ArrayList;
4 import java.util.ListIterator;
5
6 public class ListYapilariOrnek3
7 {
8
public static void main(String[] args)
9
{
10
ArrayList arrayList = new ArrayList();
11
12
arrayList.add(1);
13
arrayList.add(2);
14
arrayList.add(6);
15
arrayList.add(5);
16
arrayList.add(2, 3);
17
arrayList.set(3, 4);
18
19
System.out.print("Dizinin tüm elemanları : ");
20
System.out.println(arrayList);
21
System.out.print("Listenin indis numarası 3 olan
22 elemanı : ");
23
System.out.println(arrayList.get(3));
24
}
25 }
26
Ekran çıktısı:
Dizinin tüm elemanları : [1, 2, 3, 4, 5]
1
Listenin indis numarası 3 olan elemanı
2
:4
Örnekte arrayList.add(2, 3) satırına kadar elemanları sırayla listemize ekledik.
Bu satırda 2 numaralı indis değerine 3 kaydedilir ve daha sonraki elemanların
indis değerleri bir ötelenir. Daha sonraki satırda iseset() metodu ile 3 indis
değerli elemanı 4 ile değiştirdik. En son satırda get() metodu ile 3 indis değerli
elemanı ekrana yazdırdık.
Ders 131 - LinkedList (Bağlı Liste)
Bağlı liste yapısında adından da anlaşılabileceği gibi elemanlar eklenilirken
aralarına bir bağ konulur. Bu bağ hem tek yönlü hem de çift yönlü olabilir.
Bağlı liste yapısı List arayüzünün alt sınıfıdır. Dolayısıyla Listarayüzünün
sınıflarının kullandığı ortak metotların hepsini uygulayabilir. Fakat bu
koleksiyon yapısı listenin sonuna veri ekleme, listenin başından veri çekme gibi
bazı özelleşmiş metotlara sahiptir. Bu özelliği sayesinde bağlı liste yapısı
özelleştirilip kuyruk (Queue) veya yığıt (Stack) yapısına dönüştürülebilir.
Kuyruk ve yığıt yapıları özel öneme sahip koleksiyon tipleridir. Ancak, bu
yapıları kullanan uygulamaların çok olması nedeniyle kuyruk ve yığıt yapıları
için özelleşmiş metotlar oluşturulmuştur. Bu bölümde kuyruk ve yığıt
yapılarının nasıl oluşturulduğunu örneklerle göreceğiz.
Şimdi bağlı liste yapısını daha iyi anlayabilmek için genel bir örnek yapalım:
//ListYapilariOrnek.java - 24.04.2014
1
2 import java.util.LinkedList;
3
4 public class ListYapilariOrnek
5 {
6
public static void main(String[] args)
7
{
8
LinkedList linkedList = new LinkedList();
9
10
linkedList.add(1);
11
linkedList.add(2);
12
linkedList.add(3);
13
linkedList.addFirst(4);
14
linkedList.addLast(0);
15
16
System.out.println("Listenin tüm elemanları : " + linkedList);
17
System.out.println("Listenin ilk elemanı : " +
18 linkedList.getFirst());
19
System.out.println("Listenin son elemanı : " +
20 linkedList.getLast());
21
}
22 }
23
Ekran çıktısı:
Listenin tüm elemanları : [4, 1, 2,
1
3, 0]
2
Listenin ilk elemanı : 4
3
Listenin son elemanı : 0
Örnekte önce oluşturduğumuz bağlı listeye üç eleman ekledik. Daha
sonra addFirst() ve addLast()metodlarıyla listenin önce başına sonra da
sonuna bir eleman ekledik. Son olarak getFirst() ve getLast()metotlarıyla da
ilk ve son elemanları ekrana yazdırdık.
Kuyruk ve yığıt örneğine geçmeden önce bunları kısaca açıklayalım. Kuyruk,
ilk giren ilk çıkar mantığını benimseyen yapıdır. Yani elemanlar
koleksiyona sondan eklenir, ancak silme işlemi
listenin başından yapılır.Yığıt yapısında ise kuyruk yapısının tam tersi mantık
vardır. Elemanlar yığıt yapısında daima listenin sonunaeklenir ve silme işlemi
listenin sonundan yapılır. Şimdi bağlı liste yapısıyla nasıl kuyruk ve yığıt
yapıldığını görelim.
Kuyruk Sınıfı:
//kuyruk.java - 24.04.2014
1
2
import java.util.LinkedList;
3
4
public class kuyruk
5
{
6
private LinkedList list = new
7
LinkedList();
8
9
public void elemanKaydet(Object
10
eleman)
11
{
12
list.addLast(eleman);
13
}
14
public Object elemanCek()
15
{
16
return list.removeFirst();
17
}
18
public Object elemanGetir()
19
{
20
return list.getFirst();
21
}
22
public boolean isEmpty()
23
{
24
return list.isEmpty();
25
}
26
}
27
Yığıt Sınıfı:
//yigit.java - 24.04.2014
1
2
import java.util.LinkedList;
3
4
public class yigit
5
{
6
private LinkedList list = new
7
LinkedList();
8
9
public void yigitaEkle(Object eleman)
10
{
11
list.addFirst(eleman);
12
}
13
public Object tepeEleman()
14
{
15
return list.getFirst();
16
}
17
public Object yigittanCek()
18
{
19
return list.removeFirst();
20
}
21
public boolean isEmpty()
22
{
23
return list.isEmpty();
24
}
25
}
26
27
Main Sınıfı:
1 //yigit.java - 24.04.2014
2
3 public class main
4 {
5
public static void main(String[] args)
6
{
7
kuyruk queue = new kuyruk();
8
yigit stack = new yigit();
9
10
for(int i = 1 ; i <= 3 ; i++)
11
{
12
queue.elemanKaydet(i);
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
stack.yigitaEkle(i);
}
System.out.println("Kuyruk(Queue) Elemanları :");
// kuyruk boş olmadığı sürece döngü çalışır.
while(!queue.isEmpty())
{
System.out.println("Kuyruktan getir :" +
queue.elemanGetir());
System.out.println("Kuyruktan getir ve sil :" +
queue.elemanCek());
}
System.out.println("Yığıt(Stack) Elemanları :");
// yığıt boş olmadığı sürece döngü çalışır.
while(!stack.isEmpty())
{
System.out.println("En tepedeki eleman: " +
stack.tepeEleman());
System.out.println("Yığıttan çekilen eleman: " +
stack.yigittanCek());
}
}
}
Ekran çıktısı:
Kuyruk(Queue)
1
Elemanları :
2
Kuyruktan getir :1
3
Kuyruktan getir ve sil :1
4
Kuyruktan getir :2
5
Kuyruktan getir ve sil :2
6
Kuyruktan getir :3
7
Kuyruktan getir ve sil :3
8
Yığıt(Stack) Elemanları :
9
En tepedeki eleman: 3
10
Yığıttan çekilen eleman: 3
11
En tepedeki eleman: 2
12
Yığıttan çekilen eleman: 2
13
En tepedeki eleman: 1
14
Yığıttan çekilen eleman: 1
Önce kullandığımız metotları kısaca açıklayalım.
Kuyruk Sınıfı:

elemanKaydet (Object eleman): Elemanı kuyruğun sonuna ekler.

elemanCek(): Kuyruğun başındaki elemanı getirir ve elemanı
kuyruktan siler.

elemanGetir(): Kuyruğun başındaki elemanı getirir.

isEmpty(): Kuyruk boş ise geriye true; dolu ise false değer döndürür.
Yığıt Sınıfı:

yigitaEkle(Object eleman): Elemanı yığıta iter.

tepeEleman(): Yığıtın en tepesindeki elemanı getirir.

yigittanCek(): Yığıtın en tepesindeki elemanı çeker ve elemanı
yığıttan siler.

isEmpty() Yığıt boş ise geriye true; dolu ise false değer döndürür.
Örnekte önce bir kuyruk (queue) ve bir yığıt (stack) yapısı oluşturduk. Daha
sonra oluşturduğumuz bu yapıların ekleme metotlarını kullanarak kuyruk ve
yığıta sırasıyla 1, 2 ve 3 elemanlarını ekledik. Sonuç olarak ekran çıktısında
kuyruk yapısından ilk elde ettiğimiz elemanın kuyruğa ilk olarak eklediğimiz
eleman olduğunu; yığıt yapısında ilk elde ettiğimiz elemanın yığıt yapısına, en
son eklediğimiz eleman olduğunu gördük.
VECTOR
Vector'ler içine eleman yüklendikçe büyüyen dizilerdir.
Temelde ArrayList koleksiyon yapısına benzemesine rağmen aralarında bir
takım performans farklılıkları vardır. Vector sınıfı senkronizedir. Bu
nedenle ArrayList sınıfı Vector sınıfından daha hızlıdır. Ayrıca Vector'lerin
kapasitesinin ne değerde artacağını uygulamalar belirleyebilir. Vector sınıfını
bir örnek üzerinden açıklayalım.
1 //VectorOrnek.java - 24.04.2014
2
3 import java.util.Vector;
4
5 public class VectorOrnek
6 {
7
public static void main(String[] args)
8
{
9
final int kapasite = 3;
10
final int artis = 4;
11
// Vector kapasitesini ve kapasite artışını verilen değerlerle
12 belirledik.
13
Vector v = new Vector(kapasite, artis);
14
15
v.add(1);
16
v.add(15);
17
v.add(19);
18
System.out.println("Vector'un kapasitesi : " + v.capacity());
19
System.out.println("İlk eleman : " + v.firstElement());
20
System.out.println("Son eleman : " + v.lastElement());
21
v.add(5);
22
System.out.println("Vector'un kapasitesi : " + v.capacity());
23
System.out.println("3. eleman : " + v.elementAt(2));
24
}
25 }
26
Ekran çıktısı:
Vector'un kapasitesi :
1
3
2
İlk eleman : 1
3
Son eleman : 19
4
Vector'un kapasitesi :
5
7
3. eleman : 19
Yukarıdaki örnekte Vector oluştururken, Vector'un kapasitesini 3 ve bu
kapasite aşıldığı anda artırılacak kapasite artış miktarını 4 olarak belirledik.
Bundan sonra vector başlangıç olarak kapasitesini 3 birim olarak belirler. Daha
sonra bu kapasite aşıldığı anda kapasitesini 4 birim artırır. İlk olarak üç eleman
ekledikten sonra Vector'un kapasitesini kontrol ettiğimizde kapasitesinin 3
olduğunu görüyoruz. Daha sonra Vector'un ilk elemanlarını ekrana yazdırıp, bir
eleman daha ekliyoruz. Bu durumda Vector'un ilk elemanlarını ekrana yazdırıp,
bir eleman daha ekliyoruz. Bu durumda Vector'un ilk kapasitesi aşılmış oluyor
ve Vector kapasitesini artış miktarı kadar artırır. Tekrar Vector'un kapasitesini
kontrol ettiğimizde kapasitesinin 7 olduğunu görüyoruz.
QUEUE (KUYRUK)
Kuyruk yapısına bağlı liste yapısında kısaca değinmiştik. Kuyruk, ilk giren ilk
çıkar (First In First Out) mantığıyla çalışır. Yani kuyruğa ilk eklenen eleman
kuyruktan ilk çıkacak elemandır. Temelde LinkedList(Bağlı Liste) yapısında
olmalarına rağmen özel önemleri olduğu için bir takım özelleşmiş metotları
kullanırlar. Kuyruk yapısı liste sınıfının en belirgin özelliği olan indis
değerleriyle işlem yapmazlar. Yani kuyruk içindeki bir elemana indis
değeriyle erişemezsiniz. Kuyruk sınıfını bir örnekle açıklayalım.
//KuyrukOrnek.java - 24.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.LinkedList;
import java.util.Queue;
public class KuyrukOrnek
{
public static void main(String[] args)
{
Queue kuyruk = new LinkedList();
// add metotuyla eleman eklerken hata alırsak uygulama exception
fırlatır.
kuyruk.add(10);
kuyruk.add(55);
kuyruk.add(7);
// offer metotuyla eleman eklerken hata alırsak geriye false değer
döner.
kuyruk.offer(66);
while(!kuyruk.isEmpty())
{
System.out.println("Sırada bekleyen eleman : " +
kuyruk.peek());
System.out.println("Sırada bekleyen elemanı getir : " +
kuyruk.poll());
}
}
}
Ekran çıktısı:
1
Sırada bekleyen eleman : 10
2
3
4
5
6
7
8
Sırada bekleyen elemanı getir :
10
Sırada bekleyen eleman : 55
Sırada bekleyen elemanı getir :
55
Sırada bekleyen eleman : 7
Sırada bekleyen elemanı getir :
7
Sırada bekleyen eleman : 66
Sırada bekleyen elemanı getir :
66
Örnekte önce bir kuyruk yapısı oluşturduk. Daha sonra bu kuyruğa
elemanlarımızı ekledik. Elemanları eklerken hangi metotla eklediğimize dikkat
etmeliyiz. Eğer uygulamanın eleman eklerken hata almamız
durumunda hata(Exception) fırlatmasını istiyorsak add() metodunu; hata
almamız durumunda geriye trueveya false değer döndürmesini
istiyorsak offer() metodunu kullanmalıyız. Elemanları ekledikten sonra
kuyruğun başında bekleyen elemanı peek() metoduyla belirledik ve ekrana
yazdırdık. Sonraki satırda ise bekleyen elemanı kuyruktan almak
için poll() metodunu kullandık. Bu metot kuyrukta sıra bekleyen elemanı bize
verir ve kuyruktan bu elemanı siler.
Ders 132 - Map Arayüzü
Map arayüzü, Collection arayüzünün bir parçası değildir. Bu arayüz,
elemanlarını anahtar değerlerle eşleştirerek saklar. Anahtar değerler arasında
kopya eleman bulundurmaya izin vermez; elemanlar arasında kopya değer
bulunabilir. Map sınıflarını anlatmadan önce, bu sınıfların kullandığı bazı
metotları açıklayalım.

containsKey(Object key): Map içerisinde referans olarak verilen
anahtar değer varsa true, yoksa falsedeğer döndürür.

containsValue(Object Value): Map içerisinde referans olarak verilen
değer varsa true, yoksa falsedeğer döndürür.

entrySet(): Map içerisindeki elemanları Set (Küme) koleksiyon öğesi
olarak verir.

get(Object key): Map içerisinden, referans olarak verilen anahtar
değere karşılık gelen elemanı verir.

keySet(): Map içerisindeki anahtarları Set(Küme) koleksiyon öğesi
olarak verir.

put(Object key, Object value): Map içerisine referans olarak verilen
elemanı anahtar değere eşleyerek kaydeder.

remove(Object key): Map içerisinden anahtar değere karşılık gelen
eleman silinir.

values(): Map içerisindeki değerleri Collection öğesi olarak verir.
HASHMAP
HashMap, Map arayüzünün bir örneğidir. Bu sınıf her elemana karşılık
bir anahtar değeri saklar. Anahtar değerler veya veriler sıralı olmak zorunda
değildir. HashMap'den çekilen verilerin sırası belirsizdir.
HashMap sınıfının performansını etkileyen bazı faktörler vardır. Başlangıç
sığası ve bu başlangıç sığasınınnasıl artacağı gibi faktörler bu gibi veri
yapılarının performansını direk etkiler. HasMap sınıfında da Başlangıç
Sığası (Initial Capacity) ve Yükleme Katsayısı (Load Factor) faktörleri
performansı etkiler. Başlangıç sığası,HashMap öğesinin ilk
tanımlanırken belirlenen sığasıdır. Yükleme katsayısı ise, sığanın belirlenen
oranda doolduğunda otomatik olarak değişeceğini gösteren orandır. Bu konu
hakkında bir örnek yaparak konuya açıklık getirelim.
1 //HashMapOrnek.java - 24.04.2014
2
3 import java.util.HashMap;
4 import java.util.Iterator;
5 import java.util.Set;
6
7 public class HashMapOrnek
8 {
9
public static void main(String[] args)
10
{
11
HashMap hash = new HashMap (10, 0.75f);
12
// başlangıç sığası 10, yükleme katsayısı 0.75 olan HashMap öğesi
13 oluşturduk.
14
15
hash.put("Bir", 1);
16
hash.put("İki", 2);
17
hash.put("Üç", 3);
18
hash.put("Dört", 4);
19
hash.put("Beş", 5);
20
hash.put("Altı", 6);
21
22
Set veri = hash.entrySet();
23
Set anahtar = hash.keySet();
24
25
System.out.println("HashMap Öğesinin verileri");
26
Iterator i = veri.iterator();
27
while(i.hasNext())
28
System.out.println(i.next());
29
30
System.out.println("HashMap Öğesinin anahtarları");
31
Iterator it = anahtar.iterator();
32
while(it.hasNext())
33
System.out.println(it.next());
34
}
35 }
36
Örnekte önce başlangıç sığası 10 olan, yükleme katsayısı 0.75 olan
bir HashMap öğesi oluşturduk. Bu rakamların yüksek
olması HashMap öğesinin performansını etkileyecek; bellek
kullanımını artıracaktır. Eğer öğeyi oluştururken başlangıç sığası ve yükleme
katsayısı tanımlamak istiyorsanız, bunu kullanacağınız verilere göre iyi
ayarlamanız gerekmektedir. Başlangıç sığası ve yükleme katsayısı
tanımlamadığınız durumda derleyici sizin için ön tanımlı değerler olan
başlangıç sığası 16 ve yükleme katsayısı 0.75 olan bir öğe oluşturacaktır.
Öğemizi oluşturduktan sonra öğemize verileri anahtar değerler
ile eşleyerek kaydettik. Buradan sonra ekran çıktısında verilerin kayıt sırası ile
elde ettiğimiz çıktının sırasının farklı olduğuna dikkatinizi çekmek
istiyorum.HashMap öğesini anlatırken söylediğimiz gibi HashMap öğesinde
verilere erişim sırası belirsizdir. Daha sonrasında HashMap öğesinin
verilerini entrySet() metodu ile oluşturduğumuz Set koleksiyon öğesine
aktardık. Aynı işlemi sonraki satırda, bu sefer HashMap öğesinin anahtarları
için yaptık. Verileri ve anahtarlarıiterator yardımıyla ekrana yazdırdık.
HashMap öğesinin anahtarları için tekrarlı öğe içermez ifadesini
kullanmıştık. Peki, tekrarlı anahtar öğesi girmeye çalıştığımızda hata verecek
mi? Bunu kısa bir örnek üzerinden anlatalım.
1
//HashMapOrnek2.java - 24.04.2014
2
3
import java.util.HashMap;
4
import java.util.Iterator;
5
import java.util.Set;
6
7
public class HashMapOrnek2
8
{
9
public static void main(String[] args)
10
{
11
HashMap hash = new HashMap();
12
13
hash.put("Bir", 3);
14
15
16
17
18
19
20
21
22
23
hash.put("İki", 4);
hash.put("Bir", 1);
hash.put("İki", 2);
hash.put("Üç", 3);
System.out.println("HashMap öğeleri : " +
hash);
}
}
Ekran çıktısı:
1
HashMap öğeleri : {Üç=3, Bir=1, İki=2}
Örnekte HashMap öğesi oluşturduk ve bu öğeye iki kere tekrarlı
anahtar içeren veri ekledik. Uygulama, tekrarlı anahtar değerleri için derleme
anında hata vermedi. Fakat sonradan eklenen ve tekrarlı anahtar içeren öğenin
verisini daha önceden var olan öğenin verisiyle değiştirdi. put() metodu,
tekrarlı anahtar içeren bir öğe eklenmek istediğinde öğenin verisini önceden var
olan öğenin verisi ile değiştirir ve önceki veriyi geriye döndürür. Eğer tekrarlı
anahtar değer yoksa geriye null değer döndürür. Tekrarlı anahtar değerlerini
kontrol etmek için uygulamanızda put() metodu için null değerini kontrol
edebilirsiniz.
LINKEDHASHMAP
LinkedHashMap, Map arayüzünün bir öğesidir. Genel
olarak HashMap ve LinkedList yapılarının özelliklerini
içerir. LinkedList koleksiyon yapısında veriler birbirine bağlanıyordu. Bu
sayede verilerin dönüş sırasını tahmin
edebiliyorduk. LinkedHashMap öğelerinde de öğelerin dönüş sırasını tahmin
edebiliriz.LinkedHashMap ile Map arayüzün öğelerinin yapabildiği işlemleri
yapabiliriz. LinkedHashMap öğesini daha iyi anlayabilmek için bir örnekle bu
öğeyi açıklayalım.
1 //LinkedHashMapOrnek.java - 24.04.2014
2
3 import java.util.LinkedHashMap;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Set;
public class LinkedHashMapOrnek
{
public static void main(String[] args)
{
LinkedHashMap lhm = new LinkedHashMap();
// ASCII tablosundaki 65-90 arasındaki değerleri ve anahtarlarını
öğemize kaydediyoruz
for(int i = 65 ; i <= 90 ; i++)
lhm.put((char) i, i);
Set anahtarlar = lhm.keySet();
System.out.println("LinkedHashMap öğeleri");
System.out.println(lhm);
System.out.println("LinkedHashMap öğesinin anahtarları");
System.out.println(anahtarlar);
}
}
Ekran çıktısı:
LinkedHashMap öğeleri
{A=65, B=66, C=67, D=68, E=69, F=70, G=71, H=72, I=73, J=74,
1
K=75, L=76, M=77, N=78, O=79, P=80, Q=81, R=82, S=83, T=84,
2
U=85, V=86, W=87, X=88, Y=89, Z=90}
3
LinkedHashMap öğesinin anahtarları
4
[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W,
X, Y, Z]
Örnekte önce bir LinkedHashMap öğesi oluşturduk. Daha
sonrasında for döngüsü yardımıyla, ASCIItablosundan 65 - 90 arasındaki
değerleri öğemize ekledik. Ekran çıktısında da görüldüğü gibi öğeler kayıt
sırasında olduğu gibi geri dönmüş oldu. LinkedHashMap bu
özelliğiyle HashMap öğesindeki öğelerin geri dönüş belirsizliğini ortadan
kaldırıyor.
SORTEDMAP
SortedMap, Map arayüzünün alt arayüzüdür. SortedMap,
SortedSet arayüzünde olduğu gibi verileriartan sırada sıralı olarak saklar. Bu
arayüzün SortedSet arayüzünden farkı, verileri anahtarlarla
eşleyereksaklamasıdır. Bu arayüz, Map arayüzüne ekleme olarak iki metot
daha sunar. Bu metotlar ve bunların görevleri ise şöyledir:

firstKey(): Öğe içerisinde ilk anahtar değerini döndürür.

lastKey(): Öğe içerisindeki son anahtar değerini döndürür.
TREEMAP
TreeMap, içerisine girilen verileri sıralı bir biçimde tutar. Yani anahtarların
sıralı bir biçimde tutulması istediğiniz
uygulamalarınızda TreeMap kullanabilirsiniz. Diğer Map arayüzü öğelerinden
farklı bir takım metotlara sahiptir. Bunlardan bazıları ve bunların görevleri
şöyledir.

ceilingEntry(K Key): Verilen anahtar değere eşit veya ondan büyük
olan anahtar değerle eşlenmiş anahtar-veri çiftini verir. Böyle bir
anahtar yoksa null değer döndürür.

ceilingKey(K Key): Verilen anahtar değere eşit veya ondan büyük
olan anahtar değeri döndürür. Böyle bir anahtar değer yoksa null değer
verir.

descendingKeySet(): Map içerisindeki anahtar değerleri azalan sırada
verir.

descendingMap(): Map içerisindeki anahtar-veri çiftlerini azalan
sırada verir.

firstEntry(): Map içerisindeki ilk anahtar ile eşleşen anahtar veri
çiftini verir.

floorEntry(K Key): Verilen anahtar değere eşit veya ondan küçük
olan anahtar değerle eşleşmiş anahtar-veri çiftini verir. Böyle bir
anahtar değer yoksa null değer döndürür.

floorKey(K Key): Verilen anahtar değere eşit veya küçük olan
anahtar değeri döndürür. Böyle bir anahtar değer yoksa null değer
döndürür.

headMap(K Key): Verilen anahtardan küçük olan anahtar değerlerle
eşleşen anahtar-veri çiftlerini verir. Böyle bir anahtar değer
yoksa null değer döndürür.

higherEntry(K Key): Verilen anahtar değerden büyük olan anahtar
değerle eşleşmiş anahtar-veri çiftini verir. Böyle bir anahtar değer
yoksa null değer döndürür.

higherKey(K Key): Verilen anahtar değerden büyük olan anahtar
değeri verir. Böyle bir anahtar değer yoksa null değer döndürür.

lastEntry(): Map içerisindeki en büyük anahtarla eşleşen anahtar-veri
çiftini verir.

lowerEntry(K Key): Verilen anahtardan küçük olan anahtarla eşleşen
anahtar-veri çiftini verir. Böyle bir anahtar değer yoksa null değer
döndürür.

lowerKey(K Key): Verilen anahtardan küçük olan anahtar değeri
verir. Böyle bir anahtar değer yoksanull değer döndürür.

pollFirstEntry(): Map içerisindeki ilk anahtarla eşleşen anahtar-veri
çiftini verir ve bu öğeyi Mapiçerisinden siler.

pollLastEntry(): Map içerisindeki son anahtarla eşleşen anahtar-veri
çiftini verir ve bu öğeyi Mapiçerisinden siler.

subMap(K fromKey, L toKey): Verilen anahtar arasında kalan
anahtar-veri çiftlerini verir. Alt uç sıralamaya dahil, üst uç hariçtir.

tailMap(K Key): Verilen anahtara eşit veya büyük olan anahtarlarla
eşleşmiş anahtar veri çiftlerini verir. Anahtar değer yoksa null değer
döndürür.
Bu metotların bazılarını içeren bir örnekle konuyu açıklayalım.
1 //TreeMapOrnek.java - 24.04.2014
2
3 import java.util.TreeMap;
4
5 public class TreeMapOrnek
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
public static void main(String[] args)
{
TreeMap tree = new TreeMap();
tree.put(1, "Bir");
tree.put(3, "Üç");
tree.put(6, "Altı");
tree.put(4, "Dört");
tree.put(5, "Beş");
tree.put(2, "İki");
System.out.println("TreeSet öğeleri : " + tree);
System.out.print("3 veya 3 den sonraki en büyük anahtar-veri
çifti : ");
System.out.println(tree.ceilingEntry(3));
System.out.print("Azalan şekilde anahtarlar : ");
System.out.println(tree.descendingKeySet());
System.out.print("7 veya 7 den sonraki en küçük anahtar-veri
çifti : ");
System.out.println(tree.floorEntry(7));
System.out.print("4 den küçük olan anahtar veri çiftleri : ");
System.out.println(tree.headMap(4));
System.out.print("3 den büyük olan anahtar-veri çifti : ");
System.out.println(tree.higherEntry(3));
System.out.print("2 den küçük olan anahtar değeri : ");
System.out.println(tree.lowerKey(2));
System.out.print("Map içerisindeki son veri(Veri silinecek) : ");
System.out.println(tree.pollLastEntry());
System.out.print("2 ile 4 değerleri arasındaki anahtar-veri
çiftleri : ");
System.out.println(tree.subMap(2, 5));
System.out.print("4 ve 4 den büyük olan anahtar veri çiftleri :
");
System.out.println(tree.tailMap(4));
}
}
Ekran çıktısı:
1 TreeSet öğeleri : {1=Bir, 2=İki, 3=Üç, 4=Dört, 5=Beş, 6=Altı}
2 3 veya 3 den sonraki en büyük anahtar-veri çifti : 3=Üç
3 Azalan şekilde anahtarlar : [6, 5, 4, 3, 2, 1]
4
5
6
7
8
9
10
7 veya 7 den sonraki en küçük anahtar-veri çifti : 6=Altı
4 den küçük olan anahtar veri çiftleri : {1=Bir, 2=İki, 3=Üç}
3 den büyük olan anahtar-veri çifti : 4=Dört
2 den küçük olan anahtar değeri : 1
Map içerisindeki son veri(Veri silinecek) : 6=Altı
2 ile 4 değerleri arasındaki anahtar-veri çiftleri : {2=İki, 3=Üç,
4=Dört}
4 ve 4 den büyük olan anahtar veri çiftleri : {4=Dört, 5=Beş}
Örnekte ilk önce bir TreeMap oluşturduk ve
verilerimizi TreeMap öğesine rastgele ekledik. Ekran çıktısında ilk
sırada TreeMap öğelerinin erişim sırasına baktığımızda verileri rastgele ve
düzensiz eklememize rağmen verilerin sıralı bir biçimde TreeMap içerisinde
saklandığını görüyoruz. Sonraki satırda kullandığımız metotla 3 veya 3'den
sonra en büyük olan anahtarla eşleşen anahtar-veri çiftini ekrana yazdırıyoruz.
Daha sonraki satırda ise 5 metoduyla Map içerisindeki anahtarları azalan
sırada ekrana yazdırıyoruz. Bir sonraki satırda floorEntry() metoduyla 7 veya
7'den sonraki en küçük anahtarla eşleşen anahtar-veri çiftini ekrana
yazdırdık. headMap() metoduyla 4'den küçük olan anahtar-veri çiftlerini
ekrana yazdırdık. Bir sonraki satırdahigherEntry() metoduyla 3'den büyük olan
anahtarla eşleşen anahtar-veri çiftini ekrana yazdırdık. Sonraki
satırda lowerKey() metoduyla 2'den küçük olan anahtar değeri ekrana
yazdırdık. pollLastEntry() metoduylaMap içerisindeki son anahtar-veri çiftini
ekrana yazdırdıktan sonra metot son veriyi Map içerisinden sildi. Sonraki
satırda subMap() metoduyla 2 ile 5 arasındaki verileri ekrana yazdırdık fakat
metotun tanımında da anlatıldığı üzere 2 sıralamaya dahil edilirken, 5
sıralamaya dahil edilmedi. En son satırda tailMap() metoduyla 4 ve 4'den
büyük olan anahtar-veri çiftlerini ekrana yazdırdık ve uygulamayı sonlandırdık.
Ders 133 - Olay Yönetimine Giriş
Bu dersimizde Java'da önemli bir yeri olan olaylar ve olayların yönetimine
ilişkin durumları açıklamaya çalışacağız. Olaylar, görsel tabanlı
uygulamaların temelini oluştururlar. Olaylar hakkında hiç bilgi sahibi
olmadan, görsel tabanlı uygulama yazmak neredeyse imkansızdır.
Uygulamamız çalışırken kullanıcı tarafından uygulamaya yapılan her etki bir
olaydır. Bu bazen bir fare tıklaması olabileceği gibi bazen ise farenin hareket
etmesi durumudur. Java'da olayları tam olarak anlayabilmemiz için olayları
meydana getiren dört unsuru bilmemiz gerekir. Bunlar;

Olay Kaynağı (Event Source): Olayı tetikleyen nesnedir. Çoğu
zaman dış bir birimin durumunun değişmesi olayı tetikleyen ana neden
olmuştur. Fare ve klavye gibi nesneler, en çok olay üreten birimler
olmuşlardır.

Olay Nesnesi (Event Object): Olayı tetikleyen kod parçasıdır. Olay
ile ilgili bilgileri tutar.

Olay Dinleyicileri (Event Listener): Dinleyici bir olayın tetiklenme
durumu için oluşturulmuş nesnedir. Adından da anlaşılacağı üzere
sürekli özelleştiği olayı dinler ve olay gerçekleştiği zaman Event
Handlingnesnesini tetikler.

Olay İşleyicileri (Event Handling): Olay dinleyicisi tarafından ilgili
olay yakalandığında, bu olaya aitEvent Handling nesnesi tetiklenir ve
bu nesne altındaki kod parçalarının çalışması sağlanır.
Ders 134 - Olay Sınıfları
Bu başlık altında Java'daki olayları gerçekleştiren sınıfları anlatacağız. Olay
sınıfları, olay yönetimi bölümünün büyük bir kısmını oluşturmaktadır. Bu
sebeple olay yönetimine olay sınıflarıyla başlamamız daha uygun olacaktır.
Java'da burada işleyeceğimizden fazla olay olduğunu bilmeliyiz. Biz bu
kısımda en çok kullanılan olay sınıflarını işleyeceğiz. Olay sınıflarına
geçmeden önce, şimdi bir olayın bileşenimize nasıl eklendiğini görmek için
basit bir örnek verelim:
JButton dugme = JButton("Yeni
1
Dugme");
Olayımızı eklemeden önce yukarıdaki gibi öncelikle bileşenimizi
oluşturuyoruz.
1 dugme.addActionListener(this);
Sonrasında ise olayımızın gerçekleşip gerçekleşmediğini kontrol edecek
dinleyici bileşenimize ekliyoruz. Daha sonrasında ise, yine sınıfımız içerisinde
olayımız gerçekleştiğinde çağrılacak ilgili metodumuzun bir kopyasını
yazıyoruz.
void actionPerformed(ActionEvent ae)
1
{
2
// butona tıklanıldığında çağırılacak
3
metod
4
}
Yukarıda gördüğümüz metodun içerisine butona her tıklandığında, çalıştırmak
istediğimiz kod parçalarını yazmamız gerekmektedir. Tabi bir olayı tanımlarken
olayı yazacağımız sınıfımızın ilgili olay dinleyici sınıfınıimplement etmesi
gerekmektedir. Yukarıdaki örnekte ActionListener olay dinleyici sınıfını
kullanmaktadır. Dolayısıyla sınıfımızda bileşenlerimize olayımızı eklemeden
önce sınıfımızın ActionListener sınıfını implementetmesini sağlamalıyız.
Şimdi olay sınıflarına ve bunların bize sağladığı metotlara geçelim.
ACTIONEVENT
Tanımlı bir bileşenin etki oluşturduğunu bildiren bir olay sınıfıdır. Bir düğmeye
basıldığı gibi durumlarda oluşurlar. Bu olay sınıfının yapılandırıcı metotları
aşağıdaki gibidir.

ActionEvent (Object kaynak, int id, String komut)

ActionEvent (Object kaynak, int id, String komut, int belirtec)

ActionEvent (Object kaynak, int id, String komut, long zaman, int
belirtec)
Burada kaynak olayı başlatan nesnedir. Id ise olayın tipini integer bir değer ile
ifade eder. komut ise olayla ilişkilendirilen
karakter komut dizisidir. belirtec olay gerçekleştiğinde hangi belirteç tuşlarına
basıldığını işaret eder (Belirteç tuşları: ALT, CTRL, SHIFT ve META).
Negatif değer belirteç parametresi için bir anlam ifade etmezken , 0 değeri
hiçbir belirteç tuşuna basılmadığını gösterir. zaman parametresi ise olayın
gerçekleştiği zamanı belirtir.
Bu sınıfın bazı metotları ve kullanım amaçları şöyledir:

getActionCommand(): Olayla ilişkilendirilmiş komut adını geriye
döndürür.

getModifiers(): Olay gerçekleşirken hangi belirteç tuşlarına
basıldığını geri döndürür.

getWhen(): Olayın ne zaman meydana geldiğiyle ilgili bilgiyi geriye
döndürür.

paramString(): Olay içerisinde tanımlanmış parametre
katarlarını geri döndürür.
ADJUSTMENTEVENT
AdjustmentEvent, genellikle kaydırma çubuğu tarafından oluşturulan
olaydır. Kaydırma çubuğu birkaç durumda bu olayı üretebilir. Bu durumları
ayırt etmek için sınıf içerisinde birkaç tane değişken tanımlanmıştır. Bunlar;

ADJUSTMENT_VALUE_CHANGED: Kaydırma çubuğunun
durumunun değiştiğini gösterir.

BLOCK_DECREMENT: Kaydırma çubuğunun değerinin
düşürüldüğünü gösterir.

BLOCK_INCREMENT: Kaydırma çubuğunun değerinin artırıldığını
gösterir.

TRACK: Kaydırma çubuğunun sürüklendiğini gösterir.

UNIT_DECREMENT: Kaydırma çubuğunun ucundaki butona
kaydırma çubuğunun değerinin düşürülmesi için tıklandı.

UNIT_INCREMENT: Kaydırma çubuğunun ucundaki butona
kaydırma çubuğunun değerinin düşürülmesi için tıklandı.
Bu olayın yapılandırıcı metodu aşağıdaki gibidir:

AdjustmentEvent (Adjustable kaynak, int id, int tip, int veri)

AdjustmentEvent (Adjustable kaynak, int id, int tip, int veri,
boolean isAdjusting)
Burada kaynak olayı başlatan nesneyi belirtir. id olay tipini, tip ayarlama tipini
belirtirken veri ise ayarlanan nesneyi belirtir. isAdjusting değeri ise çoklu
ayarlama olayına izin verilip verilmediğini gösterir.
Bu sınıfın bazı metotları ve kullanım amaçları şöyledir:

getAdjustable(): Bu olay ile ilişkilendirilmiş Adjustable nesne geri
döndürülür.

getAdjustmentType(): Olay ile ilişkilendirilmiş ayarlama tipini
gönderir. Bu değer yukarıda bahsettiğimiz sabit değerlerdir.

getValue(): Ayarlama miktarı geriye döndürülür.

getValueIsAdjusting(): Çoklu ayar olaylarından biri doğru ise,
geriye true değer döndürür.
COMPONENTEVENT
Bu olay sınıfı, bileşenlerin durumları ile ilgilidir. Bir bileşenin konumu veya
boyutu gibi özellikleri değiştiğinde bu olay tetiklenir. Bir önceki olay sınıfında
da olduğu gibi olay tiplerini birbirinden ayırt etmek için değişkenler
tanımlanmıştır. Bunlar;

COMPONENT_HIDDEN: Bileşenin gizlediği durumu belirtir.

COMPONENT_SHOWN: Bileşenin görünürlük özelliğinin aktif
edildiği durumu bildirir.

COMPONENT_RESIZED: Bileşenin boyutunun değiştiğini bildirir.

COMPONENT_MOVED: Bileşenin konumunun değiştiğini bildirir.
Bu olay sınıfının yapılandırıcı metodu aşağıdaki gibidir:
ComponentEvent(Component kaynak, int
1
tip)
Burada kaynak olayı başlatan nesnedir, tip ise olayın tipini belirtir.
Bu olay sınıfının en çok kullanılan metodu ve amacı aşağıdaki gibidir:

getComponent(): Olayı başlatan bileşeni geriye döndürür.
CONTAINEREVENT
Bu olay sınıfı, bir bileşen Container nesnesine eklenildiğinde veya
çıkarıldığında oluşur. Olay sınıfımız olayları birbirinden ayırt etmek amacıyla
iki sabit oluşturmuştur. Bunlar;

COMPONENT_ADDED: Container nesnesine bileşen ekleme
durumunu kontrol eden sabit değer.

COMPONENT_REMOVED: Container nesnesinden bileşen silme
durumunu kontrol eden sabit değer.
Bu olay sınıfımızın yapılandırıcı metodu aşağıdaki gibidir:
ContainerEvent(Component kaynak, int id, Component
1
diger)
Burada kaynak olayımızı başlatan bileşen, id olayımızın tipi
ve diger Container nesnesine eklenilen veya çıkarılan bileşeni ifade
etmektedir.
Bu sınıfın en çok kullanılan bazı metotları ve metotların amaçları aşağıdaki
gibidir:

getContainer(): Bu metot, bize olayı başlatan Container nesnesini
döndürür.

getChild: Bu metot, bize Container nesnemize eklenilen veya
nesnemizden çıkarılan bileşeni döndürür.
FOCUSEVENT
Bu olay sınıfıi bileşen üzerinde herhangi bir odak alındığında veya
kaybedildiğinde tetiklenir. Olay odak alındığını ve kaybedildiğini, sınıf
içerisinde tanımladığı FOCUS_GAINED ve FOCUS_LOST değerleriyle
anlar. Bu sınıfın yapılandırıcı metotları aşağıdaki gibidir:

FocusEvent(Component kaynak, int tip)

FocusEvent(Component kaynak, int tip, boolean gecici)

FocusEvent(Component kaynak, int tip, boolean gecici,
Component diger)
Burada kaynak olayı üretecek nesne referansıdır. Tip olayın tipini belirtir
(FOCUS_GAINED veyaFOCUS_LOST). Bir diğer parametre olan gecici ise
odak yakalama olayı geçici ise true değer alır; değilsefalse değer alır. Odak
alımı başka bir bileşeni daha kapsayacaksa bu bileşen diger parametresi ile
belirtilir.
Bu sınıfın bazı metotları ve amaçları aşağıdaki gibidir:

getOppositeComponent(): diger parametresiyle
belirttiğimiz component tipindeki bileşeni döndürür.

isTemporary(): Bu metot, bize odak yakalama olayının geçici olup
olmadığını bildirir.
INPUTEVENT
Bu olay sınıfı, tüm girdi durumlarını kontrol eden olay tipidir. Bu olay sınıfı
içerisinde yapılandırıcı bir metot yoktur. Bu olay
gerçekleşirken ActionEvent olayında da olduğu gibi herhangi bir belirteç
tuşuna basılması durumunu kontrol etmek için değerler tanımlanmıştır. Bunlar;
Alt kontrol tuşunu belirtir.
ALT_MASK
AltGr kontrol tuşunu belirtir.
ALT_GRAPH_MASK
Farenin Button1 tuşunu belirtir.
BUTTON1_MASK
Farenin Button2 tuşunu belirtir.
BUTTON2_MASK
BUTTON3_MASK
CTRL_MASK
META_MASK
SHIFT_MASK
Farenin Button3 tuşunu belirtir.
Ctrl tuşunu belirtir.
Meta tuşunu belirtir. (Sun sistemlerinde
bulunur)
Shift tuşunu belirtir.
Bu olay sınıfının bazı kullanılan metotları ve bu metotların amaçları aşağıdaki
gibidir:

isAltDown(): Olay başlatıldığında Alt tuşuna basılıp basılmadığını
kontrol eder.

isAltGraphDown(): Olay başlatıldığında AltGr tuşuna basılıp
basılmadığını kontrol eder.

isControlDown(): Olay başlatıldığında Ctrl tuşuna basılıp
basılmadığını kontrol eder.

isMetaDown(): Olay başlatıldığında Meta tuşuna basılıp
basılmadığını kontrol eder.

isShiftDown(): Olay başlatıldığında Shift tuşuna basılıp basılmadığını
kontrol eder.
Yukarıdaki metotlar, boolean tipinde değer döndürür.

getModifiers(): Olay başlatıldığında hangi kontrol tuşlarına
basıldığını verir. Int tipinde değer döndürür.
ITEMEVENT
ItemEvent olayı, genelde seçim olaylarıyla ilgilenir. Bir liste öğesi
seçildiğinde, onay kutusu seçildiğinde veya onay kutusu kaldırıldığında bu olay
üretilir. Bu olay sınıfı içerisinde olay tiplerinin tanımlanması için üç adet tam
sayı tipte veri belirtilmiştir. Bunlar:

DESELECT: Kullanıcı seçilmiş olan bir öğenin seçimini kaldırdı.

SELECTED: Kullanıcı seçilmemiş olan bir öğeyi seçti.

ITEM_STATE_CHANGED: Öğenin seçim durumunun değiştiğini
gösterir. Seçili veya seçimin kaldırılmış olmasıyla ilgili bilgi vermez.
Bu sınıfın yapılandırıcı metodu aşağıdaki gibidir:
ItemEvent (ItemSelectable kaynak, int id, Object eleman, int
1
stateChange)
Burada kaynak olayı üreten nesnedir. id ise olayın tipini belirtir. eleman ise
olay tarafından etkilenen elemanı belirtir. stateChange parametresi ise bu
öğenin geçerli durumunu belirtmek için kullanılır.
Bu olay sınıfının bazı kullanılan metotları ve bu metotların amaçları aşağıdaki
gibidir:

getItem(): Olay tarafından etkilenen elemanı geriye döndürür. Object
tipinde değer döndürür.

getItemSelectable(): Olayı başlatan nesneyi geri döndürür.

getStateChange(): Olay başlatıldıktan sonra değişen durumu
döndürür (Sınıf içerisindeki değerlerden birini
döndürür. SELECTED veya DESELECTED gibi).
KEYEVENT
Bu olay sınıfı genel olarak klavye girdileriyle ilgilidir. Sınıf içerisinde
olayların tipini belirlemek için üç tip sabit değişken kullanılmıştır. Bunlar ve
anlamları şöyledir.

KEY_PRESSED: Klavyeden bir tuşa basılma durumunu belirtir.

KEY_RELEASED: Klavyeden basılan bir tuşun bırakıldığını belirtir.

KEY_TYPED: Klavyeden bir karakter girildiğini belirtir.
Bu olay tiplerinden başka kullanılan tiplerde vardır. Bunlar ise genellikle
klavyeden hangi tuşa basıldığının belirtilmesi için kullanılır. Bunlardan bazıları
ve anlamları şöyledir:
VK_CANCEL Cancel tuşunu kontrol eder.
Aşağı yön tuşunu kontrol
VK_DOWN
eder.
Yukarı yön tuşunu kontrol
eder.
Sol yön tuşunu kontrol eder.
VK_LEFT
Sağ yön tuşunu kontrol
VK_RIGHT
eder.
Enter tuşunu kontrol eder.
VK_ENTER
Caps Lock tuşunu kontrol
VK_CAPS_LOCK
eder.
VK_DELETE Delete tuşunu kontrol eder.
ESC tuşunu kontrol eder.
VK_ESCAPE
VK_UP
Tuş kontrolleri yukarıda belirttiğimizden çok fazladır. 0'dan 9'a kadar bütün
tuşların kontrol değişkeni mevcuttur. Burada sadece örnek olması açısından bir
kaçının açıklamasını verdik.
Bu olay sınıfının en çok kullanılan yapılandırıcısı aşağıdaki gibidir:
KeyEvent (Component kaynak, int id, long zaman, int belirtec, int kod, char
1
character)
Burada kaynak olayı başlatan birleşen, id olayımızın tipi, zaman olayının
gerçekleştiği zaman, belirtecolayın başlangıcında belirteç tuşlarına basılıp
basılmadığını kontrol eden parametre, kod hangi tuşun kontrolünün
yapılacağı integer tipte belirtir (VK_ENTER gibi), character ise tuş
kontrolünde tuşun bilgisinichar tipte bildirir.
Bu olay sınıfında en çok kullanılan bazı metotlar ve bu metotların amaçları şu
şekildedir:

getKeyCode(): Bu olay sırasında basılan tuşun kodunu integer tipte
geri döndürür.

getKeyChar(): Olay sırasında basılan tuşu char tipte geri döndürür.

getKeyText(int keyCode): Kodu referans olarak gönderilen tuşu
tanımlayan string tipte açıklama gönderir.

isActionKey(): Basılan tuş bir fonksiyonel tuş
ise true; değilse false değer döndürür.
MOUSEEVENT
Bu olay sınıfı farenin olaylarını kontrol eder. Farenin tıklanması, fareyi
sürükleme, fare tekerleğinin hareket ettirilmesi gibi olaylar bu sınıf altındadır.
Bu olayları birbirinden ayırmak için sınıf içerisinde bir takım değişkenler
tanımlanmıştır. Bu değişkenleri iki grup altında inceleyebiliriz. Bunlar;
Fare Olayları:

MOUSE_CLICKED: Farenin tıklanması durumunu kontrol eder
(Butona basıldı ve serbest bırakıldı).

MOUSE_ENTERED: Farenin bir bileşenin etki altına girmesi
durumunu kontrol eder.

MOUSE_EXITED: Farenin bir bileşenin etki alanından çıkması
durumunu kontrol eder.

MOUSE_PRESSED: Farenin butonuna basılması durumunu kontrol
eder.

MOUSE_RELEASED: Farenin butonunun serbest bırakılması
durumunu kontrol eder.

MOUSE_WHEEL: Farenin tekerleğinin hareket ettirilmesi durumunu
kontrol eder.
Fare hareket olayları:

MOUSE_DRAGGED: Farenin sürüklenmesi durumunu kontrol eder.

MOUSE_MOVED: Farenin taşınması durumunu kontrol eder.
MouseEvent olay sınıfımızın yapılandırıcı metotları aşağıdaki gibidir.

MouseEvent (Component kaynak, int id, long zaman, int belirtec,
int x, int y, int tikSayisi, boolean tetikleyici)

MouseEvent (Component kaynak, int id, long zaman, int belirtec,
int x, int y, int tikSayisi, boolean tetikleyici, int button)
Burada kaynak olayı üreten bileşen, id olayın tipi, zaman olayın ne zaman
gerçekleştiği, belirtec olay gerçekleşirken hangi belirteç tuşlarına
basıldığı, x ve y farenin yatay ve dikey koordinatları, tikSayisi olay ile
ilişkilendirilmiş fare tık sayısı, tetikleyici eğer olay bir açılır pencerenin
görüntülenmesini sağlayacaksa true; değilse false, button ise hangi fare
tuşunun durumunun değiştiğini gösteren değerlerdir.
Button parametresinin hangi fare tuşunun durumunun değiştiğini gösteren
değerler aldığını az önce ifade etmiştik. Bu değerler, yine sınıf içerisinde
tanımlanan tuşları birbirinden ayırt etmek için kullanılan sayısal değerlerdir.
Bunlar;

NOBUTTON: Olaylardan hiçbir fare tuşunun etkilenmediğini
gösterir.

BUTTON1: Farenin ilk tuşunu belirtir.

BUTTON2: Farenin ikinci tuşunu belirtir.

BUTTON3: Farenin üçüncü tuşunu belirtir.
Bu olay sınıfımızın en çok kullanılan bazı metotları ve amaçları aşağıdaki
gibidir.

getX(): Farenin yatay düzlemdeki X koordinatını verir.

getY(): Farenin dikey düzlemdeki Y koordinatını verir.

getPoint(): Farenin bulunduğu noktayı getirir. Point tipinde değer
döndürür.

getClickCount(): Olay için fareye tıklanma sayısını verir.

getButton(): Olaya neden olan fare tuşunu belirten sayısal değer
gönderir. Sayısal değerler yukarıda bahsettiğimiz tuş değerleridir.
MOUSEWHEELEVENT
Bu olay sınıfı farenin tekerleğini kontrol eder. MouseEvent sınıfının alt
sınıfıdır. Diğer sınıflarda olduğu gibi bu olay sınıfımızda da olayları birbirinden
ayırmak için bir takım değerler tanımlanmıştır. Bunlar;

WHEEL_BLOCK_SCROLL: Bir sayfa (block) yukarı veya aşağı
hareket ettirilmesi durumudur (Page Down veya Page Up tuşlarında
olduğu gibi).

WHEEL_UNIT_SCROLL Bir satır (unit) yukarı veya aşağı hareket
ettirilmesi durumudur. (Yön tuşlarıyla sayfa hareketlerinde olduğu
gibi).
Bu olay sınıfının yapılandırıcı metodu aşağıdaki gibidir:
MouseWheelEvent (Component kaynak, int id, long zaman, int belirtec,
1
int x, int y, int tikSayisi, int tetikleyici, int kaydirmaTipi, int
kaydirmaAdedi, int donusSayisi)
Bu olay sınıfının MouseEvent olay sınıfının alt sınıfı olduğunu belirtmiştik.
Dolayısıyla yukarıdaki parametreleri çoğu MouseEvent olayında bahsedildiği
gibidir. Farklı olan parametrelerden kaydirmaTipisayfanın satır satır veya
sayfa sayfa kaydırılma tiplerinden birini ifade eder. kaydirmaAdedi, satır satır
kaydırma için kaç satır kaydırıldığını gösterir. donusSayisi ise tekerleğin kaç
tur çevrildiğini gösterir.
Bu olay sınıfının en çok kullanılan metotlarından bazıları ve bu metotların
amaçları aşağıdaki gibidir:

getScrollAmount(): Olay içerisinde kaç satır çevrildiğini döndürür.

getScrollType(): Yukarıda bahsettiğimiz kaydırma tiplerinden birini
verir(Satır kaydırma veya sayfa kaydırma).

getWheelRotation(): Olay içerisinde fare tuşunun kaç tur çevrildiğini
verir.
TEXTEVENT
Metin nesnelerinin içeriğinin değişimini belirten olay sınıfıdır. Olay tipini
belirlemek için tek bir değişken sınıf içerisinde tanımlanmıştır. Bu değişken
şöyledir.

TEXT_VALUE_CHANGED: Metin nesnesinin içeriğinin değiştiğini
belirten durumdur.
Bu olay sınıfının yapılandırıcı metodu aşağıdaki gibidir:
1
TextEvent(Component kaynak, int id)
Burada kaynak olayı başlatan bileşendir. id ise olayımızın tipidir.
WINDOWEVENT
Bu olay sınıfı adından da anlaşılacağı üzere pencere olaylarını kontrol eder. Bu
olayları birbirinden ayırmak için sınıf içerisinde bir takım değerler
tanımlanmıştır. Bunlar şöyledir:
WINDOW_ACTIVATED
WINDOW_CLOSED
WINDOW_OPENED
Pencerenin etkinleştirilmesi durumu
Pencerenin kapatılması durumu
Pencerenin açılması durumu
Pencerenin kapatılması için etkileşimde
WINDOW_CLOSING
bulunuldu
Pencerenin etkin özelliğini yitirmesi
WINDOW_DEACTIVATED
durumu
Pencerenin simge durumuna getirilmesi
WINDOW_ICONFIED
durumu
Pencerenin simge durumunun iptal edilmesi
WINDOW_DEICONFIED
durumu
Pencerenin odak özelliğini kaybetmesi
WINDOW_LOST_FOCUS
durumu
Pencerenin durumunun değişmesi durumu
WINDOW_STATE_CHANGED
(Boyutu veya konumu gibi)
Pencerenin odak özelliğini geri kazanması
WINDOW_GAINED_FOCUS
durumu
Bu olay sınıfının en çok yapılandırıcı metotları aşağıdaki gibidir:

WindowEvent (Component kaynak, int id)

WindowEvent (Component kaynak, int id, int eskiDurum, int
yeniDurum)

WindowEvent (Component kaynak, int id, Window diger)

WindowEvent (Component kaynak, int id, Window diger, int
eskiDurum, int yeniDurum)
Burada kaynak olayı başlatan pencere nesnesi, id olayımızın
tipi, diger etkinleştirme veya odak olayı oluştuğunda gösterilecek
pencere, eskiDurum pencerenin eski durumunu ve yeniDurum ise pencerenin
yeni oluşacak durumunu ifade eder.
Bu sınıfın en çok kullanılan bazı metotları ve bu metotların amaçları aşağıdaki
gibidir:

getWindow(): Olayı başlatan pencere nesnesini döndürür.

getOldState(): Pencerenin WINDOW_STATE_CHANGED değeri
değişmeden önceki durumunu döndürür.

getNewState(): Pencerenin WINDOW_STATE_CHANGED değeri
değiştikten sonraki durumunu döndürür.
Ders 135 - Olay Dinleyicileri (Event Listeners)
Daha önceden bir olayın yapısının 4 unsurdan oluştuğundan bahsetmiştik. Bir
olayın gerçekleşebilmesi için en önemli olan iki unsurdan biridir dinleyiciler.
Olay dinleyicileri olay kaynaklarından aldığı etkileşimleri uygun olay
metoduna aktarır. Etkileşimden sonra metot altındaki kod parçası çalışır. Bu
bölümde olay dinleyicilerini ve bunların sağladıkları metotları yüzeysel olarak
anlatmaya çalışacağız.
ACTIONLISTENER
Bu dinleyici, herhangi bir eylem olayı gerçekleşme durumunu kontrol eder. Bu
dinleyici genel olarak bir tane metot sunar. Bu metot ve metodun yapısı
aşağıdaki gibidir:

actionPerformed (ActionEvent ae): Eylem olayı gerçekleştiğinde
çağrılır.
ADJUSTMENTLISTENER
Bu dinleyici, ayarlama olaylarını kontrol eder. Bu dinleyici birimi genel olarak
bir tane metot sunar. Bu metot ve yapısı aşağıdaki gibidir:

adjustmentValueChanged (AdjustmentEvent ae): Olayı çağıran
bileşenin ayarlama değeri değiştiğinde çağrılır.
COMPONENTLISTENER
Bu dinleyici, bir bileşenin üzerine yapılan etki olaylarını kontrol eder. Dinleyici
bize genel olarak dört adet metot sunar. Bu metotlar ve yapıları aşağıdaki
gibidir.

componentResized (ComponentEvent ce): Bileşen yeniden
boyutlandırıldığında çağrılır.

componentMoved (ComponentEvent ce): Bileşenin konumu
değiştiğinde çağrılır.

componentShown (ComponentEvent ce): Bir bileşen
aktifleştirildiğinde çağrılır.

componentHidden (ComponentEvent ce): Bir bileşen gizlendiğinde
çağrılır.
CONTAINERLISTENER
Container nesnemize bileşen eklenildiğini veya çıkarıldığını kontrol eden
dinleyici birimidir. Bu dinleyici sınıfı bize iki metot sunar. Bunlar ve amaçları
şöyledir:

componentAdded (ContainerEvent ce): Container nesnemize bir
bileşen eklenildiğinde çağrılır.

componentRemoved (ContainerEvent ce): Container nesnemizden
bir bileşen çıkarıldığında çağrılır.
FOCUSLISTENER
Bu dinleyici birimi, olayı çağıran nesne odak kazandığında veya odak
kaybettiğinde çalışır. Bize iki adet metot sunar. Bunlar ve bu metotların yapıları
aşağıdaki gibidir:

focusGained (FocusEvent fe): Olayı başlatan nesne odak aldığında
çağrılır.

focusLost (FocusEvent fe): Olayı başlatan nesne odak kaybettiğinde
çağrılır.
ITEMLISTENER
Bu dinleyici birimi, bir öğenin durumunun değişip değişmediğini kontrol eden
birimdir. ItemListener bize tek bir metot sunar. Bu metot ve yapısı aşağıdaki
gibidir:

ItemStateChanged (ItemEvent ie): Öğe durumu değiştiğinde
çağrılır.
KEYLISTENER
Bu dinleyici birimi klavye tuşlarına basılıp basılmadığını kontrol eder. Bu
dinleyici sınıfı üç metot sunar. Bu metotlar ve metotların amaçları aşağıdaki
gibidir.

keyPressed (KeyEvent ke): Klavyeden bir tuşa basıldığında çağrılır.

keyReleased (KeyEvent ke): Klavyeden basılan tuş serbest
bırakıldığında çağrılır.

keyTyped (KeyEvent ke): Klavyeden bir karakter girildiğinde
çağrılır.
MOUSELISTENER
Bu dinleyici arabirimleri farenin tuşlarına basılma olayını kontrol eder. Bu
dinleyici sınıfı beş metot sunar. Bu metotlar ve görevleri aşağıdaki gibidir:

mouseClicked (MouseEvent me): Farenin tuşuna basılıp serbest
bırakılma (tıklanma) durumu gerçekleştiğinde çağrılır.

mouseEntered (MouseEvent me): Fare bir bileşenin üzerine
geldiğinde çağrılır.

mouseExited (MouseEvent me): Fare üzerinde olduğu bir bileşenden
ayrıldığında, bu metot çağrılır.

mousePressed (MouseEvent me): Farenin tuşuna basıldığında
çağrılır.

mouseReleased (MouseEvent me): Farenin bir tuşu basılı durumdan
serbest bırakılma durumuna geçtiğinde çağrılır.
MOUSEMOTIONLISTENER
Bu dinleyici birimi, fenerin hareketlerini kontrol eden birimdir. Bu dinleyici
sınıfı iki metot sunar. Bu metotlar ve metoların görevleri aşağıdaki gibidir:

mouseDragged (MouseEvent me): Fare tuşuna basılı durumda
sürüklendiği zaman çağrılır.

mouseMoved (MouseEvent me): Fare tuşu basılı olmadan
sürüklendiği durumlarda çağrılır.
MOUSEWHEELLISTENER
Bu dinleyici birimi, fare tekerleğinin hareket ettirilmesini kontrol eden birimdir.
Bu sınıf bize bir metot sunmaktadır. Bu metot ve yapısı aşağıdaki gibidir:

mouseWheelMoved (MouseWheelEvent mwe): Fare tekerleği
hareket ettiği durumda çağrılır.
TEXTLISTENER
Bu dinleyici birimi, metin nesnelerinde veya metin tabanlı bileşenlerdeki metin
değişimlerini kontrol eden birimdir. Bu dinleyici sınıfı bize bir metot sunar. Bu
metot ve metodumuzun görevi aşağıdaki gibidir:

textChanged(TextEvent te): Metin değişimi durumlarında çağrılır.
WINDOWFOCUSEDLISTENER
Bu dinleyici birimi, pencerenin odak kazandığı veya odak kaybettiği
durumlarda tetiklenir. Bu birim bize iki metot sunar. Bu metotlar ve metotların
görevleri aşağıdaki gibidir:

windowGainedFocus (WindowEvent we): Pencere odak kazandığı
durumda çağrılır.

windowLostFocus (WindowEvent we): Pencere odak kaybettiği
durumda çağrılır.
WINDOWLISTENER
Bu dinleyici birimi, pencere ile ilgili olayları kontrol eden birimdir. Bu birim
içerisinde bize yedi tane metot sunulur. Bu metotlar ve metotların görevleri
aşağıdaki gibidir.

windowActivated (WindowEvent we): Pencere etkinleştirildiğinde
çağırılır.

windowDeactivated (WindowsEvent we): Pencere aktifliğini
kaybettiğinde çağırılır.

windowClosed (WindowEvent we): Pencere kapandığında çağırılır.

windowClosing (WindowEvent we): Pencere kapatılmak için
etkileşimde bulunduğunda çağrılır.

windowOpened (WindowEvent we): Pencere açıldığında çağırılır.

windowIconfied (WindowEvent we): Pencere simge durumuna
getirildiğinde çağırılır.

windowDeiconfied (WindowEvent we): Pencere simge durumundan
geri getirildiğinde çağırılır.
Ders 136 - Fare ve Klavye Olay Metodlarının Kullanımı
Bu dersimizde en çok kullanılan olaylar olan fare ve klavye olaylarına örnek
vereceğiz. Daha önceki derslerimizde de anlattığımız gibi
fare MouseListener, MouseMotionListener ve MouseWheelListenerdinleyic
i sınıflarını kullanmaktaydı. Klavye olaylarında ise sadece KeyListener olayı,
klavye durumlarını karşılıyordu. Şimdi öncelikle klavye daha sonra farenin en
çok kullanılan olaylarına örnek verelim.
1 //klavyeOlayOrnekleri.java - 24.04.2014
2
3 import java.awt.EventQueue;
4 import java.awt.event.KeyEvent;
5 import java.awt.event.KeyListener;
6
7 import javax.swing.JFrame;
8 import javax.swing.JLabel;
9
10 public class klavyeOlayOrnekleri extends JFrame implements
11 KeyListener
12 {
13
// implement edildi
14
JLabel etiket = new JLabel("etiket");
15
String metin = "";
16
17
public static void main(String[] args)
18
{
19
EventQueue.invokeLater(
20
new Runnable()
21
{
22
public void run()
23
{
24
try
25
{
26
klavyeOlayOrnekleri init = new
27 klavyeOlayOrnekleri();
28
init.setVisible(true);
29
}
30
catch (Exception e)
31
{
32
e.printStackTrace();
33
}
34
}
35
});
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 }
}
// bileşenlerimizi yapılandıran metod
public klavyeOlayOrnekleri()
{
super("Klavye Olayları");
add(etiket);
// bileşenimiz çerçevemize eklendi
addKeyListener(this);
// olay dinleyicimiz eklendi.
setSize(550, 100);
}
@Override
public void keyPressed (KeyEvent ke)
{
metin += "Klavyeden bir tuşa basıldı -";
etiket.setText(metin);
}
@Override
public void keyReleased (KeyEvent ke)
{
metin += "Klavyeden basılan tuş serbest bırakıldı.";
etiket.setText(metin);
}
@Override
public void keyTyped (KeyEvent ke)
{
char tus = ke.getKeyChar();
metin += "Klavyeden basılan tuş : " + tus + " - ";
etiket.setText(metin);
}
Yukarıdaki örnekte GUI bileşenlerini kullandık. Bir sonraki konuda GUI
bileşenleri ve bunların nasıl yapılandırılacağını anlatılcaktır.
Metotların anlatımına geçmeden önce sınıfımızın KeyListener dinleyici
sınıfını implement aldığına dikkat edelim. Bileşenlerimizi yapılandıran yapıcı
metodumuz içerisinde bileşenlerimizi ekledikten sonra, KeyListenerdinleyici
sınıfımızı çerçevemize ekledik. KeyListener sınıfı bundan sonra çerçevemiz
içerisinde gerçekleşecek klavye olaylarını dinleyecek. Daha sonra bu dinleyici
sınıfının bize sunduğu metotları kullandık. Daha öncede anlattığımız
gibi keyPressed() metodu, klavyeden bir tuşa basıldığı anda
çalışıyor, keyReleased() metodu klavyeden basılan tuş serbest bırakıldığında
çrğrılıyor ve keyTyped() ise klavyeden bir karakter girildiğinde çalışıyordu.
Yukarıdaki olay klavyeden h tuşuna basıldığında gerçekleşmiştir. Örnek
sayesinde olay metotlarımızın sırasının nasıl olduğunu görmüş oluyoruz.
Şimdi fare olay metotlarını kullanacağımız bir örnek yapalım.
1 //fareOlayOrnekleri.java - 24.04.2014
2
3 import java.awt.Container; // java.awt.*;
4 import java.awt.EventQueue;
5 import java.awt.GridLayout;
6 import java.awt.event.MouseEvent;
7 import java.awt.event.MouseListener;
8 import java.awt.event.MouseMotionListener;
9
10 import javax.swing.JFrame;
11 import javax.swing.JLabel;
12
13 public class fareOlayOrnekleri extends JFrame implements
14 MouseListener, MouseMotionListener
15 {
16
JLabel etiket1 = new JLabel("etiket1");
17
JLabel etiket2 = new JLabel("etiket2");
18
19
public static void main(String[] args)
20
{
21
EventQueue.invokeLater(
22
new Runnable()
23
{
24
public void run()
25
{
26
try
27
{
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
fareOlayOrnekleri init = new fareOlayOrnekleri();
init.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
// bileşenlerimizi yapılandıran metod
public fareOlayOrnekleri()
{
super("Fare Olayları");
Container con = getContentPane();
setLayout(new GridLayout());
con.add(etiket1);
con.add(etiket2);
// bileşenlerimiz çerçevemize eklendi
addMouseListener(this);
addMouseMotionListener(this);
// olay dinleyicilerimiz eklendi
setSize(550, 100);
}
@Override
public void mouseDragged(MouseEvent me)
{
etiket1.setText("Fare sürüklendi.");
}
@Override
public void mouseMoved(MouseEvent me)
{
etiket1.setText("Farenin yeri değişti.");
int x = me.getX();
int y = me.getY();
etiket2.setText("Fare koordinatları X:" + x + " Y:" + y);
}
@Override
public void mouseClicked(MouseEvent me)
{
etiket1.setText("Fare tıklandı.");
}
@Override
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 }
94
public void mouseEntered(MouseEvent me)
{
etiket1.setText("Fare etki altına girdi.");
}
@Override
public void mouseExited(MouseEvent me)
{
etiket1.setText("Fare etki alanından çıktı.");
}
@Override
public void mousePressed(MouseEvent me)
{
etiket1.setText("Fare butonuna basıldı.");
}
@Override
public void mouseReleased(MouseEvent me)
{
etiket1.setText("Fare butonu serbest bırakıldı.");
}
Uygulamamızda yine daha önceki uygulamamızda kullandığımız gibi GUI
bileşenlerini kullandık. Yapıcı metodumuz içerisinde fare
dinleyicilerimizi ekledik. Bundan sonraki kısımda olay gerçekleştiğinde
çağrılacak metotları yazdık.
Ders 137 - GUI (Graphical User Interface) Nedir?
GUI'yi Türkçeye Grafiksel Kullanıcı Arayüzü olarak çevirebiliriz. GUI,
Java'da form kontrollerini kullandığımız görsel kısımdır. GUI ile kullanıcılar
fare ve form kontrolleri sayesinde uygulamayı daha kolay kullanabilirler.
Şimdiye kadar önceki derslerimizde yaptığımız uygulamaları konsol üzerinden
yaptık. Profesyonel uygulamalarda konsol ortamı tercih edilmez. Bu yüzden
grafiksel arayüzü öğrenmeyi bizim için bir zorunluluk olarak sayabiliriz. GUI
bileşenlerini Eclipse üzerinden anlatacağımızı daha önceden belirtmiştik.
Standart Eclipse kurulumunda GUI bileşenleri bulunmamaktadır. Bu yüzden bir
sonraki bölümde Eclipse üzerinde GUI kurulumunu anlatacağız.
Ders 138 - GUI Kurulumu
Eclipse üzerinde GUI ile uygulama geliştirebilmek için birden fazla Plugin bulunmaktadır. Biz bu bölümdeSwing Plug-in'lerini kullanacağız. Bu
bileşenleri kurabilmek için internet bağlantısı gerekecetir. Kuruluma geçmeden
önce internet bağlantınızı kontrol ediniz.
Eclipse'e Swing Plug-in'lerini kurabilmek için Eclipse
üzerinden Help menüsünden Install New Softwareseçeneğini seçiyoruz.
Daha sonra karşımıza aşağıdaki şekildeki gibi bir pencere açılacak. Bu
pencerede Work with bölümünde açılır seçenek menüsünden --All Available
Sites-- seçeneğini seçtikten sonra, alt pencereye seçeneklerin gelmesi için bir
süre beklememiz gerekecektir.
Bir süre bekledikten sonra menümüze aşağıdaki şekildeki gibi seçenekler
gelecektir. Listedeki seçenekler arasından General Purpose Tools seçeneğini
bulup, seçeneğimizi genişletmek için yanındaki üçgen işaretine tıklayalım.
Seçeneklerimizi genişlettikten sonra alt seçenekler arasından aşağıdaki
şekildeki seçenekleri bulup işaretleyelim.
Alt seçeneklerimizi seçtikten sonra bir sonraki aşamaya geçmek için
menümüzden Next butonuna tıklayalım.
Bir sonraki adımda karşımıza kuracağımız bileşenleri gösteren özet sayfası
çıkacaktır. Next butonuna tıklayıp bir sonraki aşamaya geçelim. Bu bölümde
karşımıza kurulum sözleşmesi çıkacaktır. Kurulum sözleşmesini
onaylayıp Finish butonuna tıklayalım.
Bu bölümden sonra Eclipse bizim için bileşenleri internetten indirip kuracaktır.
Bileşenlerin indirilip kurulması tamamlandıktan sonra Eclipse'yi yeniden
başlatın. Eclipse'yi yeniden başlattıktan sonra GUI bileşenleri kullanıma hazır
olacaktır.
Ders 139 - GUI Projesi Oluşturma
Java'da GUI projesi iki yöntemle oluşturulabilir. Birincisi ve en çok
kullanacağımız yöntem; Eclipse IDEüzerinden oluşturmaktır. İkincisi
ise GUI projesini oluşturduğumuz sınıfın Java form bileşenlerini kod
yardımıyla miras alma yöntemidir. Bu dersimizde ikisine de örnek vererek
açıklamaya çalışacağız. Şimdi derleyicinin bizim için otomatik kod
oluşturmasına örnek verelim.
İlk olarak yukarıdaki resimdeki gibi bir Java projesi oluşturmak için proje
oluşturma penceresini açıyoruz. Daha sonrasında açılan pencerede projemize
isim verip, Finish butonuyla projemizi oluşturuyoruz.
Projemiz yukarıdaki resimde görüldüğü gibi oluşturuldu. Projemiz içerisinde
başlangıç olarak projemizin kodlarının bulunacağı src (source) klasörünü ve
varsayılan olarak gelen Java sistem kütüphanelerinigörüyoruz.
Daha sonrasında src klasörümüz seçili iken resimdeki gibi
projemize Swing menüsü altından JFramebileşenini ekliyoruz.
Açılan pencerede ilk bölümde JFrame nesnemizin ekleneceği kaynak klasör,
ikinci bölümde paket ismimiz, üçüncü bölümde JFrame nesnemize
vereceğimiz isim ve üst sınıf bilgisi bulunuyor. Biz bu kısımda sadece ikinci ve
üçüncü bölüme isim vereceğiz. Paket ismimizi ve JFrame nesnemizin ismini
belirledikten sonra, Finish butonuna basarak JFrame nesnemizi oluşturuyoruz.
JFrame nesnemiz oluşturulduktan sonra şekildeki gibi projemize
eklenecektir. JFrameFormu.javasınıfına çift tıkladığımızda aşağıdaki gibi bir
kod yapısıyla karşılaşacağız.
1 package javaGuiProjemiz;
2
3 import java.awt.BorderLayout;
4 import java.awt.EventQueue;
5
6 import javax.swing.JFrame;
7 import javax.swing.JPanel;
8 import javax.swing.border.EmptyBorder;
9
10public class JFrameFormu extends JFrame {
11
12 private JPanel contentPane;
13
14 /**
15 * Launch the application.
16 */
17 public static void main(String[] args) {
18
EventQueue.invokeLater(new Runnable() {
19
public void run() {
20
try {
21
JFrameFormu frame = new JFrameFormu();
22
frame.setVisible(true);
23
} catch (Exception e) {
24
e.printStackTrace();
25
}
26
}
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42}
});
}
/**
* Create the frame.
*/
public JFrameFormu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
}
Bu derleyicinin bizim için otomatik oluşturduğu bir kod parçasıdır. Biz
bileşenleri menüden form üzerine bıraktıkça, derleyici bizim için bileşenleri
form üzerinde otomatik yapılandıracak kod parçaları oluşturacaktır.
Konu başlangıcında GUI projelerinin iki şekilde oluşturulabileceğini
söylemiştik. İlk yöntem derleyicinin bizim için otomatik oluşturmasıydı. İkinci
yöntem ise, yukarıdaki kodda görüldüğü gibi bileşenleri sınıf üzerinde miras
alarak el ile oluşturma yöntemidir. Sınıfımızın
başlangıcında JFrame bileşenini miras (extends) aldığına dikkatimizi verelim.
Derslerimizde örneklerimizi daha çok kod üzerinden oluşturacağız dolayısıyla
ikinci yöntemi daha sık kullanacağız.
Sınıfımıza çift tıkladığımızda açılan pencerede, sol alt kısımdaki Source |
Design sekmelerinden Designsekmesine tıklayarak, JFrame bileşeninin
tasarımını görebiliriz.
Ders 140 - Swing
Swing bileşenleri Java'da GUI uygulamaları oluştururken kullanacağımız görsel
bileşenlerdir. JavadaSwing bileşenlerinden önce AWT bileşenleri
kullanılmaktaydı. AWT bileşenleri asıl amacına ulaşamayınca Java 2.0 ile
Swing bileşenleri ortaya çıktı. Swing bileşenleri AWT üzerine kurulmuştur.
Dolayısıyla Swing bileşenleri AWT metodlarını kullanmaktadır.
Bu bölümde Swing bileşenlerine değineceğiz. Swing paketlerindeki sınıf ve
bileşenlerin sayısı çok fazladır. Biz bu bölümde sadece bir kısmını
inceleyeceğiz.
SWING BİLEŞENLERİ
Sonraki derslerimizde sırasıyla en fazla kullanılan Swing bileşenlerinin yapısını
inceleyeceğiz ve bunlar hakkında örnekler yapacağız. Sırasıyla işleyeceğimiz
bileşenler şunlardır.

JFrame

Container

JLabel

JButton

JTextField

JComboBox

JRadioButton

JCheckBox

JToggleButton

JTable

JList

JScrollPane

JTabbbedPane
Ders 141 - JFrame
Java bileşenlerine geçmeden önce JFrame nesnesini ve bu nesnesinin
metodlarını öğrenmeliyiz. JFramenesnesi, üzerinde GUI bileşenlerini tutar ve
temel pencere metodları ile pencere olaylarınıngerçekleştirilmesini sağlar.
Bundan sonra işleyeceğimiz bütün görsel nesneler bu bileşen üzerinde
konumlandırılacaktır. Bir örnek üzerinden JFrame bileşenimizi anlatmaya
devam edelim.
1 //JFrameOrnegi.java - 25.04.2014
2
3 import javax.swing.*;
4
5 public class jFrameOrnegi extends JFrame
6 {
7
public jFrameOrnegi()
8
{
9
super("Pencere bileşinimiz");
10
// üst sınıfımızın yapılandırıcısını çağırdık
11
12
this.setSize(300, 400);
13
// penceremizin boyutunu ayarladık
14
this.setAlwaysOnTop(true);
15
// bu metod ile pencerenin her zaman en üstte olması durumu
16 ayarlanır
17
this.setVisible(true);
18
// penceremizi görünür yaptık.
19
this.setResizable(false);
20
// penceremizin boyutlandırılabilir özelliğini false yaptık
21
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
22
// kapama butonuna basıldığında pencerenin durumunu
23 belirtiyoruz
24
25
26
27
28
29
30 }
}
public static void main(String[] args)
{
jFrameOrnegi j = new jFrameOrnegi();
}
Örneğimizde görüldüğü gibi bir pencere oluşturduk ve bu pencerenin
özelliklerini JFrame sınıfının bize sağladığı metodlar yardımıyla değiştirdik.
JFrame sınıfının metodları, bazı durumlarda bu bileşeni oluşturmaktan daha
büyük öneme sahip olabilir. Bu bileşenin bazı önemli metodları ve bu
metotların görevleri şöyledir.

add(): Bu metot ile JFrame üzerinde bileşenler ekleyebiliriz.

getContentPane(): Oluşturulan formun modelini getirir.

getDefaultCloseOperation(): Formun kapama butonuna basıldığında
nasıl davranacağı bilgisini verir.

getLayout(): Bileşenin kullandığı Layout (yerleşim düzeni) bilgisini
getirir.

getMaximumSize(): Bileşenin alabileceği maksimum boyutu en boy
cinsinden gönderir.

getMinimumSize(): Bileşenin alabileceği minimum boyutu en boy
cinsinden gönderir.

getSize(): Bileşenin anlık boyutunu en boy cinsinden gönderir.

getTitle(): Bileşenin başlık bilgisini gönderir.

isAlwaysOnTop(): Pencerenin her zaman üstte olma durumunu
boolean değer tipinde geri döndürür.

isResizable(): Pencerenin boyutlandırılabilir olup olmadığı bilgisini
boolean değer tipinde geri döndürür.

isVisible(): Pencerenin görünürlük durumunu boolean değer tipinde
geri döndürür.

setAlwaysOnTop (boolean deger): Pencerenin her zaman üstte olma
durumunu ayarlar.

setBounds (int x, int y, int en, int boy): Bu metot, bileşenlerin
ekleneceği koordinatları ve bileşenin boyutlarını ayarlar. Metot
parametrelerinde x eklenilecek bileşenin x eksenindeki noktası, y ise y
eksenindeki noktasıdır. Diğer parametrelerden en ve boy ise bileşenin
en ve boy özelliklerini ayarlar.

setDefaultCloseOperation (int operation): Bu metot, kapama
butonuna basıldığında formun nasıl davranacağını belirtir. Metodun
parametresi sınıf içerisinde tanımlı sabitlerdir. Bu sabitlerden bazıları
ve görevleri şöyledir:
o
EXIT_ON_CLOSE: Formun kapanmasını sağlar.
o
DISPOSE_ON_CLOSE: Formun kapanmasın
sağlar. EXIT_ON_CLOSE'dan farkı ise, bu sabit ile
tanımlanan form kapanırsa tüm program
kapanmaz. EXIT_ON_CLOSE ile tanımlanan form
kapandığında bütün pencereler kapanacaktır.
o
DO_NOTHING_ON_CLOSE: Kapama butonuna
basıldığında hiç bir olay gerçekleştirilmez.
o
HIDE_ON_CLOSE: Pencereyi gizler. RAM üzerindeki
bilgileri tutar ve kullanıcının pencereyi tekrar çağırmasını
bekler. Kullanıcı tekrar çağırana kadar pencere bilgileri hazır
olarak bekletilir.

setResizable (boolean deger): Pencerenin boyutlandırılabilir
özelliğini ayarlar.

setSize (int en, int boy): Pencerenin boyutlarını en boy cinsinden
belirler.

setVisible (boolean deger): Pencerenin görünürlük özelliğini ayarlar.
Ders 142 - Container
Container nesneleri, bileşenleri üzerinde tutmaya yararlar. Ders 141 JFrame dersinde JFrame'i anlatırken nesneleri üzerinde tutabileceğinden
bahsetmiştik. JFrame bileşeni, tüm bileşenleri aynı özellikte tutar. Yani aynı
yerleşim düzeninde veya aynı arkaplan resmiyle birlikte
tutar. Container bileşenini ise bu noktata bileşenlerin durumunu özelleştirmek
için kullanabiliriz. Container bileşenlerini aşağıdaki örnekteki gibi
oluşturabiliriz.
1 //containerOrnegi.java - 25.04.2014
2
3 import java.awt.BorderLayout;
4 import java.awt.Container;
5 import java.awt.GridLayout;
6
7 import javax.swing.*;
8
9 public class containerOrnegi extends JFrame
10 {
11
public containerOrnegi()
12
{
13
super("Formumuz");
14
Container con = getContentPane();
15
// container bileşenini oluşturduk ve formumuzun modelini bu bileşen
16 içerisine aldık
17
con.setLayout(new BorderLayout());
18
// bileşenimizin yerleşim tipini belirledik
19
con.add(new JLabel("etiket bileşeni1"));
20
// bileşen içerisine etiket bileşenini ekledik
21
Container con2 = getContentPane();
22
// yine bir container bileşeni oluşturduk ve formumuzun modelini
23 aldık
24
con2.setLayout(new GridLayout());
25
// bileşenimizin yerleşim tipini belirledik
26
con2.add(new JLabel("etiket bileşeni2"));
27
// bileşen içerisine etiket ekledik.
28
setVisible(true);
29
setSize(300, 300);
30
// formumuzun özelliklerini ayarladık
31
}
32
33
public static void main(String[] args)
34
{
35
containerOrnegi c = new containerOrnegi();
36
}
37 }
Ders 143 - JLabel
JLabel, Swing bileşenlerinin en temel bileşenlerindendir. Gayet basit bir yapısı
vardır. Belki de en çok kullanacağımız bileşen JLabel'dir.
JLabel bileşeni en temel olarak etiket görevi görür. Çoğu
zaman JLabel bileşeninin Text özelliğinden yararlanarak,
diğer Swing bileşenlerinin görevini belirtmek için kullanırız. Yazacağımız bazı
uygulamalardaJLabel bileşeninin Text özelliğinin değiştirmemiz gerekecektir.
Şimdi JLabel bileşeninin kullanımını ve bazı özelliklerini işleyeceğimiz bir
örnek yapalım.
1 //JLabelOrnegi.java - 25.04.2014
2
3 import java.awt.Container;
4 import java.awt.EventQueue;
5 import java.awt.GridLayout;
6
7 import javax.swing.JFrame;
8 import javax.swing.JLabel;
9
10 public class JLabelOrnegi extends JFrame
11 {
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// uygulamalar başlatılıyor
public static void main(String[] args)
{
EventQueue.invokeLater (new Runnable()
{
public void run()
{
try
{
JLabelOrnegi frame = new JLabelOrnegi();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
// bileşenleri yapılandıran metod
public JLabelOrnegi()
{
super("JLabel Örneği");
Container con = getContentPane();
con.setLayout(new GridLayout());
/* Başlığı "JLabel Örneği" olan bir pencere oluşturduk ve
üzerine
bir yerleşim ekledik. */
JLabel lblNewLabel = new JLabel("JLabel kullanımı
örneği");
con.add(lblNewLabel);
JLabel lblNewLabel1 = new JLabel("İlk Swing bileşeni
örneğimiz");
con.add(lblNewLabel1);
setSize(400, 200);
setVisible(true);
/* yeni bir JLabel bileşeni oluşturduk ve bu bileşeni daha
önceden
oluşturduğumuz pencere üzerine ekledik, pencerenin
boyutunu
belirledik */
}
}
İlk olarak main metodumuz içerisinde bileşenlerimizi yapılandıracak metodu
çağırdık. Bu metod içerisinde önce super() metodu ile penceremizin
başlığını belirledik. Daha sonrasında bir Container nesnesi oluşturup bu
nesnenin yerleşimini GridLayout olarak ayarladık. Bundan sonraki kısımda iki
adet JLabel bileşeni oluşturduk ve JLabel bileşenlerimizin Text özelliğini
yapılandırıcı metod yardımıyla belirledik. Oluşturduğumuz bu
bileşenlerin Text özelliğini belirledikten sonra Container nesnemize ekledik.
Son olarak çerçevemizinboyutunu ve görünürlük özelliğini de belirledikten
sonra işlemi sonlandırdık.
JLabel bileşenlerimizin Text özelliklerini yapılandırıcı metot ile
belirlediğimizi bir önceki paragrafta söylemiştik. Bu
bileşenimizin Text özelliğini farklı bir metot ile değiştirmek
mümkündür. setText() metodu yardımıyla JLabel bileşenimizin Text özelliğini
değiştirebilir. getText() metodu yardımıyla JLabel bileşenimizin
mevcut Text özelliğini String olarak getirebiliriz. Metotların nasıl
kullanıldığını görmek adına yapılandırıcı metodumuzu değiştirerek bir örnek
yapalım.
1 //JLabelOrnegi2.java - 25.04.2014
2
3 import java.awt.Container;
4 import java.awt.EventQueue;
5 import java.awt.GridLayout;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import javax.swing.JFrame;
import javax.swing.JLabel;
public class JLabelOrnegi2 extends JFrame
{
// uygulamalar başlatılıyor
public static void main(String[] args)
{
EventQueue.invokeLater (new Runnable()
{
public void run()
{
try
{
JLabelOrnegi2 frame = new JLabelOrnegi2();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
// bileşenleri yapılandıran metod
public JLabelOrnegi2()
{
super("JLabel Örneği");
Container con = getContentPane();
con.setLayout(new GridLayout());
/* Başlığı "JLabel Örneği" olan bir pencere oluşturduk ve
üzerine
bir yerleşim ekledik. */
JLabel lblNewLabel = new JLabel("JLabel kullanımı
örneği");
con.add(lblNewLabel);
JLabel lblNewLabel1 = new JLabel("İlk Swing bileşeni
örneğimiz");
con.add(lblNewLabel1);
JLabel lblNewLabel2 = new JLabel();
lblNewLabel2.setText(lblNewLabel.getText());
con.add(lblNewLabel2);
setSize(600, 200);
setVisible(true);
53
/* yeni bir JLabel bileşeni oluşturduk ve bu bileşeni daha
54 önceden
55
oluşturduğumuz pencere üzerine ekledik, pencerenin
boyutunu
belirledik */
}
}
Metotların anlaşılması için daha önceden yazdığımız kodda ufak değişiklikler
yaptık. Daha önceden yapılandırıcı metot sayesinde
belirlediğimiz JLabel bileşenimizin Text özelliğini burada setText() metodu
ile belirledik. Daha sonrasında üçüncü bir JLabel bileşeni oluşturduk ve bu
bileşenin Text özelliğini ilk
oluşturduğumuz JLabel bileşenimizin Text özelliğini getText() metodu ile
getirerek bu bileşenimize aktardık.
Ders 144 - JButton
Bu bileşenimiz tetikleyici bir
bileşendir. .NET platformundaki Button bileşeninin Java platformundaki
karşılığıdır. JButton bileşeni üzerinde metin veya resim gibi nesneleri
tutabilir.
JButton bileşenine tıklandığında ActionListener()'ın actionPerformed olayı
tetiklenir. Bu olay tetiklendiği anda, altında bulunan kod satırlarını işleme
koyar. Buton bileşeni üzerine komut eklemek
istediğimizdesetActionCommand() metodunu kullanırız. Bu komutu daha
sonradan elde etmek istediğimizde olay nesnesi
içerisinde getActionCommand() metodu yardımıyla, üzerine tıklanılan
butonun komutunu elde edebiliriz.
Şimdi buton bileşenini daha iyi anlayabilmek için bir örnek yapalım.
1 //JButtonOrnegi.java - 25.04.2014
2
3 import java.awt.Container;
4 import java.awt.EventQueue;
5 import java.awt.GridLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8
9 import javax.swing.JButton;
10 import javax.swing.JFrame;
11 import javax.swing.JLabel;
12
13 public class JButtonOrnegi extends JFrame implements
14 ActionListener
15 {
16
JLabel etiket = new JLabel("Sonuç burada olacak.");
17
// uygulama başlatılıyor
18
public static void main(String[] args)
19
{
20
EventQueue.invokeLater(
21
new Runnable()
22
{
23
public void run()
24
{
25
try
26
{
27
JButtonOrnegi cerceve = new JButtonOrnegi();
28
cerceve.setVisible(true);
29
}
30
catch (Exception e)
31
{
32
e.printStackTrace();
33
}
34
}
35
});
36
}
37
// bileşenler yapılandırılıyor.
38
39
public JButtonOrnegi()
40
{
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
super("JButton Örneği");
Container con = getContentPane();
setLayout(new GridLayout());
// container nesnesi oluşturup yerleşim tipimizi belirledik
JButton dugme = new JButton("6 + 2");
dugme.setActionCommand("+");
dugme.addActionListener(this);
con.add(dugme);
/* ilk butonumuzu oluşturduk sonrasında butonumuza
komut
verip container nesnesine ekledik */
dugme = new JButton("6 * 2");
dugme.setActionCommand("*");
dugme.addActionListener(this);
con.add(dugme);
/* ikinci butonumuzu oluşturduk sonrasında butonumuza
komut
verip container nesnesine ekledik */
dugme = new JButton("6 / 2");
dugme.setActionCommand("/");
dugme.addActionListener(this);
con.add(dugme);
/* üçüncü butonumuzu oluşturduk sonrasında butonumuza
komut
verip container nesnesine ekledik */
con.add(etiket);
setSize(600, 100);
setVisible(true);
// JLabel bileşenimizi ekledik ve çerçeve boyutunu
belirledik
}
// düğme tıklandığında gerçekleşecek olay
@Override
public void actionPerformed(ActionEvent e)
{
String text = e.getActionCommand();
int sayi1 = 6;
int sayi2 = 2;
if (text.equals("+"))
{
87
etiket.setText("Sonuç: " + String.valueOf(sayi1 +
88 sayi2));
89
}
90
else if (text.equals("*"))
91
{
92
etiket.setText("Sonuç: " + String.valueOf(sayi1 *
93 sayi2));
94
}
else if (text.equals("/"))
{
etiket.setText("Sonuç: " + String.valueOf(sayi1 / sayi2));
}
}
}
Bu örneğimizde diğerlerinden farklı olarak
örneğimize ActionEvent kullanacağımız için örneğimizin bu
sınıfıimplement etmesini sağladık. Kodumuzda ilk önce ana sınıfımızı
oluşturduk ve bu ana sınıfımız içerisinde bileşenlerimizi yapılandıracak
sınıfımız içerisinde yine ilk olarak bir Container nesnesi oluşturduk ve
yerleşim tipimizi belirledik. Daha sonrasında butonlar oluşturarak
bunların komutlarını belirledik ve butonlarımızıçerçevemize ekledik.
Butonlarımızı oluşturup komutlarını belirledikten sonra,
hepsine ActionListenereklediğimize dikkat edelim. Bundan sonraki kısımda
butona tıklanıldığında gerçekleşecek olayın ayrıntılarını belirledik. Butona
tıklandığında ActionListener'in actionPerformed olayının tetiklendiğinden
bahsetmiştik.actionPeformed olayımızın içerisine çalışacak kodları yazdık.
Buna göre eğer buton bileşenimizin komutu + ise uygulama iki sayıyı
toplayıp JLabel bileşeni üzerinde gösterecek. Diğer durumlarda da komuta
göre işlem değişecek.
Yukarıdaki örneği geliştirerek bir hesap makinası yapmamız mümkündür.
Butonların komut özelliğine sayılar için sayı değerlerini ve işlemler için
işlem tiplerini vererek basit bir hesap makinası geliştirebiliriz.
Ders 145 - JTextField
JTextField, Java'da belki de en çok kullanacağımız swing bileşeni olacaktır.
En genel kullanımı, kullanıcıdan veri girilmesi istenildiği
durumdur. JTextField bileşeninin içeriğini getText() metodu yardımıyla
almamız mümkündür.
JTextField, .NET platformundaki TextBox bileşeninin Java platformundaki
karşılığıdır. Şimdi JTextFieldbileşeninin kullanımını daha iyi anlayabilmek
için bir örnek yapalım. Aşağıdaki örnek iki JTextField'e girilen sayıları sınır
olarak alır ve bu sınırlar arasındaki asal sayıların
adedini bulup, JLabel bileşenine aktarır.
1 //JTextFieldOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import java.awt.event.*;
5 // bu örneğimizde awt nin içindeki tüm sınıfları * ile aldık.
6 import javax.swing.*;
7
8 public class JTextFieldOrnegi extends JFrame implements
9 ActionListener
10 {
11
JLabel etiket;
12
JTextField metinKutusu1;
13
JTextField metinKutusu2;
14
JButton dugme;
15
16
// uygulama başlatılıyor
17
public static void main(String[] args)
18
{
19
EventQueue.invokeLater(
20
new Runnable()
21
{
22
public void run()
23
{
24
try
25
{
26
JTextFieldOrnegi cerceve = new
27 JTextFieldOrnegi();
28
cerceve.setVisible(true);
29
} catch (Exception e)
30
{
31
e.printStackTrace();
32
}
33
}
34
});
35
}
36
// bileşenler yapılandırılıyor
37
public JTextFieldOrnegi()
38
{
39
super("JTextField Örneği");
40
Container con = getContentPane();
41
setLayout(new GridLayout());
42
// container nesnesi oluşturup yerleşim tipimizi belirledik
43
etiket = new JLabel("Sonuç burada olacak");
44
con.add(etiket);
45
// etiketi oluşturduk ve ekledik
46
metinKutusu1 = new JTextField();
47
con.add(metinKutusu1);
48
metinKutusu2 = new JTextField();
49
con.add(metinKutusu2);
50
// JTextField bileşenlerini oluşturup ekledik
51
52
dugme = new JButton("Asal sayıları bul");
53
dugme.addActionListener(this);
54
con.add(dugme);
55
setSize(800, 100);
56
setVisible(true);
57
// JButton bileşenimizi oluşturup ActionListener ekledik
58
}
59
60
// butona tıklanıldığında bu olay çalışacak
61
@Override
62
public void actionPerformed(ActionEvent ae)
63
{
64
int ilk = Integer.parseInt(metinKutusu1.getText());
65
int son = Integer.parseInt(metinKutusu2.getText());
66
int asalSayisi = 0;
67
68
for (int i = ilk ; i <= son ; i++)
69
{
70
int bolenSayisi = 0;
71
for (int bolen = 2 ; bolen < i ; bolen++)
72
{
73
if(i % bolen == 0)
74
bolenSayisi++;
75
}
76
if (bolenSayisi == 0)
77
asalSayisi++;
78
}
79
etiket.setText("Bulunan asal sayı adedi: " +
80 String.valueOf(asalSayisi));
}
}
Kodumuzda yine her zaman yaptığımız gibi bir ana sınıf oluşturduk. Bu ana
sınıf, bileşenlerimizi yapılandıracak metodu çağırdı. Bu metot içerisinde önce
bir Container nesnesi oluşturup daha sonra yerleşim tipimizi belirledik. Daha
sonra sırasıyla JLabel ve JTextField bileşenlerimizi
oluşturup çerçevemize ekledik. Bundan sonraki kısımda JButton oluşturduk
ve JButton'umuza ActionListener ekledik. ActionListenerolayımızın altına
girilen sayılar arasındaki asal sayı adedini bulabilmek için kodlarımızı
yazdık. JTextFieldbileşenimizin text özelliğini JLabel bileşenimizde olduğu
gibi getText() metodu yardımıyla elde ettik. JLabelbileşenimize bulduğumuz
sayıyı setText() metodu yardımıyla yazdırdık.
Ders 146 - JComboBox
JComboBox, yani açılır liste kutuları; adından da anlaşılacağı gibi bize açılır
bir liste sunar. Aynı anda sadece bir eleman seçmemize izin verir. Seçili
elemanın özelliklerini belirli metotlar yardımıyla almamız
mümkündür. JComboBox seçili elemanın değişmesi durumunda diğer
bileşenlerden farklı olarak bir olay tetiklenir. Bu
olay itemStateChanged() olayıdır. Seçili eleman her değiştiğinde bu olay
tetiklenir ve her seferinde olay altında yazılan kod parçaları çalışır.
Şimdi JComboBox bileşenini ve bahsettiğimiz bu olayı anlayabilmek için bir
örnek yapalım.
1 //JComboBoxOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import javax.swing.*;
6
7 public class JComboBoxOrnegi extends JFrame implements
8 ItemListener
9 {
10
JLabel etiket;
11
JLabel etiket1;
12
JComboBox combo;
13
14
// uygulama başlatılıyor
15
public static void main(String[] args)
16
{
17
EventQueue.invokeLater(
18
new Runnable()
19
{
20
public void run()
21
{
22
try
23
{
24
JComboBoxOrnegi cerceve = new
25 JComboBoxOrnegi();
26
cerceve.setVisible(true);
27
}
28
catch (Exception e)
29
{
30
e.printStackTrace();
31
}
32
}
33
});
34
}
35
// bileşenler yapılandırılıyor
36
public JComboBoxOrnegi()
37
{
38
super("JComboBox Örneği");
39
Container con = getContentPane();
40
setLayout(new GridLayout());
// container nesnesi oluşturup yerleşim tipimizi belirledik
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
combo = new JComboBox();
combo.addItem("Edirne");
combo.addItem("Kırklareli");
combo.addItem("Tekirdağ");
combo.addItem("İstanbul");
combo.addItem("Çanakkale");
con.add(combo);
combo.addItemListener(this);
/* JComboBox bileşenimizi oluşturduk,
* içine verileri ekledik ve Item Listener olayını ekledik */
etiket = new JLabel("Seçilen eleman");
con.add(etiket);
etiket1 = new JLabel("Elemanın indis değeri");
con.add(etiket1);
setSize(600, 100);
setVisible(true);
// JLabel bileşenimizi tanımladık ve form boyutunu ayarladık
}
@Override
public void itemStateChanged(ItemEvent isc)
{
String komboIcerik;
int indis;
komboIcerik = (String) combo.getSelectedItem();
indis = combo.getSelectedIndex();
etiket.setText(komboIcerik);
etiket1.setText(String.valueOf(indis));
}
}
Uygulamamızı kısaca açıklamamız gerekirse,
uygulamamız JComboBox bileşeninin ItemStateChangeolayını kullanarak
seçili elemanı ve elemanının indis değerini JLabel bileşenine yazdırıyoruz.
Yazdığımız kodda diğer örneklerimizden farklı olarak JComboBox bileşenini
ekledik ve bu bileşenimize elemanları addItem()metodu yardımıyla ekledik.
Daha sonrasında değişen eleman durumlarında içeriği alabilmemiz
için JComboBoxbileşenimize bir ItemListener ekledik. Olayımız içerisinde
ise seçili eleman her değiştiğinde JLabel bileşeninintext özelliğinin buna bağlı
olarak değişmesini sağladık.
Ders 147 - JRadioButton
JRadioButton, sadece tek bir seçeneği seçmek gibi durumlarda
kullanırız. JRadioButton bileşeni sayesinde kullanıcıya birçok seçenek verip,
kullanıcıdan bir tane seçenek seçmesini isteyip, daha sonra bu seçenekle ilgili
olayı işleme koyabiliriz. JRadioButton bileşenlerini kullanacağımız zaman
bunları bir grup içerisinde yapılandırmamız daha doğru olacaktır. Grup
içerisinde yapılandırmamızın ana sebebi; sadece bir tek doğru seçeneğin olması
görüşüdür. Farklı gruplardaki seçenekleri farklı gruplar altında
yapılandırabiliriz.
JRadioButton bileşenlerinin ana görevinin tek bir seçeneği seçmek olduğunu
söylemiştik. Bu durumda seçenekleri kontrol etmek veya seçenek değişiminde
farklı işlemlere yönlendirmek için bir takım olaylar
kullanabiliriz. JRadioButton seçim değişimlerini kontrol eden
olay ActionListener arabirimininactionPerformed() olayıdır. Bu olay altında
belirlediğiniz grup için hangi düğmenin seçili olduğunu bulabilirsiniz.
Şimdi JRadioButton bileşenini ve olaylarını daha iyi anlamak için bir örnek
yapalım.
Aşağıdaki örnek JTextField içerisindeki metinin text özelliklerini değiştiren
bir örnektir.
1 //JRadioButtonOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import javax.swing.*;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class JRadioButtonOrnegi extends JFrame implements
ActionListener
{
JTextField textBox;
JRadioButton rb1, rb2, rb3, rb4;
ButtonGroup grup;
// uygulama başlatılıyor
public static void main(String[] args)
{
EventQueue.invokeLater(
new Runnable()
{
public void run()
{
try
{
JRadioButtonOrnegi cerceve = new
JRadioButtonOrnegi();
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
// bileşenler yapılandırılıyor
public JRadioButtonOrnegi()
{
super("JRadioButton Örneği");
Container con = getContentPane();
setLayout(new FlowLayout());
// container nesnesi oluşturup yerleşim tipimizi belirledik
textBox = new JTextField("ElektroArge Elektronik Araştırma
Geliştirme Platformu.");
con.add(textBox);
//JTextField oluşturduk ve varsayılan metnimizi girdik.
grup = new ButtonGroup();
rb1 = new JRadioButton("Normal", true);
con.add(rb1);
grup.add(rb1);
rb1.addActionListener(this);
rb2 = new JRadioButton("Kalın", false);
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
con.add(rb2);
grup.add(rb2);
rb2.addActionListener(this);
rb3 = new JRadioButton("Eğik", false);
con.add(rb3);
grup.add(rb3);
rb3.addActionListener(this);
rb4 = new JRadioButton("Kalın ve Eğik", false);
con.add(rb4);
grup.add(rb4);
rb4.addActionListener(this);
/* JRadioButton bileşenlerimizi oluşturduk ve
* bu bileşenleri tek bir grup altında topladık */
setSize(350,130);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent ae)
{
String font = ae.getActionCommand();
if (font.equals("Normal"))
textBox.setFont(new Font("sansserif", Font.PLAIN, 12));
else if (font.equals("Kalın"))
textBox.setFont(new Font("sansserif", Font.BOLD, 12));
else if (font.equals("Eğik"))
textBox.setFont(new Font("sansserif", Font.ITALIC, 12));
else if (font.equals("Kalın ve Eğik"))
textBox.setFont(new Font("sansserif", Font.BOLD +
Font.ITALIC, 12));
}
}
Uygulamamız basit olarak JTextField bileşeni içerisindeki
metinin Font özelliğini JRadioButtonbileşenlerinin aldığı değerlere göre
değiştiriyor. Yazdığımız kodda yapılandırıcı metod içerisinde diğer
uygulamalarımızdan farklı
olarak JRadioButton ekledik. JRadioButton eklerken, bu bileşenin
yapılandırıcı metoduna boolean bir parametre ekledik. Bu uygulama
başladığında varsayılan olarak seçili gelekJRadioButton bileşenini
gösterecektir. JRadioButton bileşenlerimizi oluşturduktan sonra, hepsini daha
önceden oluşturduğumuz bir grup altında topladık. Hepsini bir grup altında
toplamasaydık bütün JRadioButton bileşenlerini aynı anda seçebilecektik.
Tek grup altında toplamak bize tek bir doğru seçenek olmasını sağlıyor.
Olayımız içerisinde önce hangi JRadioButton bileşeninin seçili olduğunu
bulduktan sonra buna göre işlemlerimizi yaptık.
Ders 148 - JCheckBox
JCheckBox, JRadioButton bileşenine çok benzer fakat bir yön ile bu
bileşenden ayrılır. JRadioButtonbileşenini önceki dersimizde anlatırken tek
bir doğru seçeneğin seçilmesi gerektiğini anlatmıştık, burada ise durum
farklıdır. JCheckBox bileşenlerinde birden fazla seçenek işaretlenebilir ve
buna göre işlem yapılabilir.
Şimdi bu bileşeni daha iyi anlamak ve olaylarını daha iyi görebilmek için
bununla ilgili bir örnek yapalım.
1 //JCheckBoxOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import javax.swing.*;
6
7 public class JCheckBoxOrnegi extends JFrame implements
8 ItemListener
9 {
10
JLabel etiket1;
11
JCheckBox cb, cb1, cb2, cb3, cb4;
12
13
// uygulama başlatılıyor
14
public static void main(String[] args)
15
{
16
EventQueue.invokeLater(
17
new Runnable()
18
{
19
public void run()
20
{
21
try
22
{
23
JCheckBoxOrnegi cerceve = new
24 JCheckBoxOrnegi();
25
cerceve.setVisible(true);
26
} catch (Exception e)
27
{
28
e.printStackTrace();
29
}
30
}
31
});
32
}
33
// bileşenler yapılandırılıyor.
34
public JCheckBoxOrnegi()
35
{
36
super("JCheckBox Örneği");
37
Container con = getContentPane();
38
setLayout(new FlowLayout());
39
// container nesnesi oluşturup yerleşim tipimizi belirledik
40
JLabel etiket = new JLabel("Bildiğiniz programlama dillerini
41 seçin");
42
con.add(etiket);
43
44
cb = new JCheckBox("Java");
45
con.add(cb);
46
cb.addItemListener(this);
47
cb1 = new JCheckBox("C");
48
con.add(cb1);
49
cb1.addItemListener(this);
50
cb2 = new JCheckBox("C++");
51
con.add(cb2);
52
cb2.addItemListener(this);
53
cb3 = new JCheckBox("C#");
54
con.add(cb);
55
cb3.addItemListener(this);
56
cb4 = new JCheckBox("Android");
57
con.add(cb4);
58
cb4.addItemListener(this);
59
// JCheckBox bileşenlerimizi oluşturduk ve olaylarını ekledik
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
etiket1 = new JLabel();
con.add(etiket1);
setSize(300, 150);
setVisible(true);
}
@Override
public void itemStateChanged(ItemEvent ie)
{
String diller = "Bildikleriniz: ";
if(cb.isSelected())
diller += cb.getText();
if(cb1.isSelected())
diller += ", " + cb1.getText();
if(cb2.isSelected())
diller += ", " + cb2.getText();
if(cb3.isSelected())
diller += ", " + cb3.getText();
if(cb4.isSelected())
diller += ", " + cb4.getText();
etiket1.setText(diller);
}
}
Uygulamamız kısaca seçili olan JCheckBox bileşenlerini bulup,
bunların text özelliğini bir JLabelbileşenine aktarıyor. Yazdığımız bu
uygulamada diğer uygulamalardan farklı olarak JCheckBox bileşeni oluşturduk
ve bunları çerçevemize ekledik. Olayımız içerisinde ise
hangi JCheckBox bileşenlerinin seçili olduğunu bulduk ve
bunların text özelliğini bir JLabel bileşenine aktardık.
Ders 149 - JToggleButton
JToggleButton, JButton bileşeninin farklı bir durumudur. JButton bileşenine
bir kez tıkladığımızda anlıkdüğmeye tıklamış ve geri çekmiş (serbest
bırakmış) olursunuz. JToggleButton bileşeninde ise durum biraz farklıdır. Bu
bileşene bir kez tıkladığınızda bir daha tıklayana kadar düğme basılı kalır. Bir
daha tıkladığınızda düğmeyi serbest bırakmış olursunuz.
JToggleButton bileşeni her ne kadar JButton bileşenine benzese de yapısal
olarak JCheckBox bileşenine benzer. Bu yüzden JToggleButton bileşeni
aynı JCheckBox bileşeni
gibi ItemListener arabirimininitemStateChanged() olayını
kullanır. JToggleButton bileşeninde aynen JCheckBox bileşeninde olduğu
gibiisSelected() metodunu kullanmamız mümkündür.
Şimdi bu bileşen hakkında bir örnek yaparak konuyu daha iyi anlamaya
çalışalım.
1 //JToggleButtonOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import javax.swing.*;
6
7 public class JToggleButtonOrnegi extends JFrame implements
8 ItemListener
9 {
10
JLabel etiket, etiket1, etiket2;
11
JToggleButton gecisliDugme;
12
13
// uygulama başlatılıyor
14
public static void main(String[] args)
15
{
16
EventQueue.invokeLater(
17
new Runnable()
18
{
19
public void run()
20
{
21
try
22
{
23
JToggleButtonOrnegi cerceve = new
24 JToggleButtonOrnegi();
25
cerceve.setVisible(true);
26
} catch (Exception e)
27
{
28
e.printStackTrace();
29
}
30
}
31
});
32
}
33
// bileşenler yapılandırılıyor.
34
public JToggleButtonOrnegi()
35
{
36
super("JToggleButton Örneği");
37
Container con = getContentPane();
38
setLayout(new FlowLayout());
39
// container nesnesi oluşturup yerleşim tipimizi belirledik
40
etiket1 = new JLabel("Basılma sayısı: ");
41
con.add(etiket1);
42
etiket = new JLabel("0");
43
con.add(etiket);
44
45
gecisliDugme = new JToggleButton("Bas\\Serbest bırak");
46
con.add(gecisliDugme);
47
gecisliDugme.addItemListener(this);
48
// JToggleButton bileşenimizi oluşturduk ve olayını ekledik
49
50
etiket2 = new JLabel("JToggleButton serbest bırakıldı");
51
con.add(etiket2);
52
setSize(300, 100);
53
setVisible(true);
54
}
55
56
@Override
57
public void itemStateChanged(ItemEvent ie)
58
{
59
int sayac = Integer.parseInt(etiket.getText());
60
61
if(gecisliDugme.isSelected())
62
{
63
sayac++;
64
etiket.setText(String.valueOf(sayac));
65
etiket2.setText("JToggleButton'a basıldı");
66
} else {
etiket2.setText("JToggleButton serbest bırakıldı");
67
68
69
}
}
}
Uygulamamızda ilk önce yerleşim düzenimizi seçip bir Container bileşeni
oluşturduk. Daha sonrasında önceden oluşturduğumuz etiketlerimizi
yapılandırarak Container nesnemize ekledik. Daha
sonrasındaJToggleButton bileşenimizi oluşturup buna bir ItemListener olayı
atadık. Olayımız içerisinde JToggleButtonbileşenine her basıldığında artacak
bir sayaç tanımladık. Eğer bileşenimizin isSelected() özelliği true ise
sayacımızı etiketimize yazdırıyor ve JToggleButton bileşenimize basıldığını
gösteren bir başka bildirimi diğer etikete yazdırıyor. Eğer bileşenimizin bu
özelliği false ise bileşenimizin serbest bırakıldığını gösteren bildirim
etiketimize yazdırılıyor.
Ders 150 - JTable
JTable, verileri satırlar ve sütunlar olarak görüntülemeye yarayan bir
bileşendir. Bu bileşeni çok boyutlu bir dizinin görsel hali olarak
düşünebiliriz. Swing bileşenleri arasında en karmaşık bileşen olduğunu
söylersek herhalde yanılmış olmayız. JTable bileşenini birçok yapılandırıcı
metod sunar. En fazla kullanılan yapıcı metod aşağıdaki gibidir.
JTable (Object icerik[][], Object
1
sutunlar[])
Yukarıdaki yapılandırıcı metod iki parametre alır ve bunlardan ilki içerisinde
barındıracağı verileri tutan bir dizidir. Dizinin iki boyutlu olduğuna dikkatimizi
verelim. Bu boyutlar, satır ve sütunlar içindir. İkinci parametre ise sütun
isimlerini tutan bir dizidir.
Bir JTable bileşeni birden fazla olayla ilişkilidir. Kullanıcı tablodan bir eleman
seçtiğindeListSelectionEvent olayı tetiklenir. Tablo içerisinde verilerden biri
değiştirildiğinde TableModelEvent olayı tetiklenir. Bu olayların hepsini
kullanmak zorunda değiliz. Eğer tablomuzu sadece veri tutmak veya verileri
ekrana çıktı gibi göstermek istiyorsak, bu olayları kullanmayabiliriz.
Şimdi JTable bileşeni ve bu bileşenin seçim olayı hakkında bir örnek yaparak
konuyu daha iyi anlamaya çalışalım.
1 //JTableOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import javax.swing.*;
5 import javax.swing.event.*;
6
7 public class JTableOrnegi extends JFrame implements
8 ListSelectionListener
9 {
10 JTable tablo;
11 JLabel etiket, etiket1;
12
13 // uygulama başlatılıyor
14 public static void main(String[] args)
15 {
16
EventQueue.invokeLater(
17
new Runnable()
18
{
19
public void run()
20
{
21
try
22
{
23
JTableOrnegi cerceve = new JTableOrnegi();
24
cerceve.setVisible(true);
25
} catch (Exception e)
26
{
27
e.printStackTrace();
28
}
29
}
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
});
}
// bileşenler yapılandırılıyor.
public JTableOrnegi()
{
super("JTable Örneği");
Container con = getContentPane();
setLayout(new FlowLayout());
// container nesnesi oluşturup yerleşim tipimizi belirledik
Object[] sutun = {"İl", "Plaka Kodu", "Bölge"};
// sütun isimlerini tanımladık
Object[][] veriler = {
{"Edirne", 22, "Marmara"},
{"İstanbul", 34, "Marmara"},
{"Kırıkkale", 71, "İç Anadolu"},
{"İzmir", 35, "Ege"},
{"Trabzon", 61, "Karadeniz"},
{"Hatay", 31, "Akdeniz"},
{"Gazi Antep", 27, "Güney Doğu Anadolu"},
{"Malatya", 44, "Doğu Anadolu"},
{"Giresun", 28, "Karadeniz"} };
// tablo içerisinde gösterilecek verileri tanımladık
tablo = new JTable(veriler, sutun);
con.add(new JScrollPane(tablo));
tablo.setCellSelectionEnabled(true);
/* tablomuzu oluşturduk,
* çerçevemize ekledik ve seçilebilir özelliğini aktif yaptık */
ListSelectionModel model = tablo.getSelectionModel();
model.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
model.addListSelectionListener(this);
/* tablomuza ListSelectionListener olayını ekleyebilmek
* için model ekledik ve seçeneklerini ayarladık */
etiket = new JLabel("Seçili Veri: ");
con.add(etiket);
etiket1 = new JLabel();
con.add(etiket1);
setSize(500, 200);
setVisible(true);
}
@Override
public void valueChanged(ListSelectionEvent ie)
76 {
77
int sutunIndisi = tablo.getSelectedColumn();
78
int satirIndisi = tablo.getSelectedRow();
79
Object seciliEleman;
80
81
seciliEleman = tablo.getValueAt(satirIndisi, sutunIndisi);
82
etiket1.setText(String.valueOf(seciliEleman));
83 }
84}
Bu uygulamamızda diğerlerinden farklı olarak tablo oluşturduk. Tablo
oluştururken önce sütun isimlerini, daha sonra ise tablo içerisinde
gösterilecek verileri tanımladık. Daha sonra tablomuzun yapılandırıcı metodu
ile bu verileri tablomuza aktardık. Tablo
bileşenimize ListSelectionListener ekleyebilmek için önce modeloluşturduk.
Daha sonra modelimiz üzerinden tablomuzda sadece bir hücrenin seçili
olabilmesi içinselectionMode() metodu ile seçim modunu değiştirdik. Olayımız
ise her hücre değişimde tetiklenecektir. Olayımız içerisinde önce tablomuzda ki
seçili olan satır ve sütun indis değerlerini bulduk ve bu indis değerlerine göre
seçili olan elemanı bulduk ve JLabel bileşenimize aktardık.
Ders 151 - JList
JList, adından da anlaşılacağı gibi bir liste elemanıdır. İçerisindeki
elemanlardan bir veya daha fazlasınıseçmeye izin verir. En çok
kullanılan swing bileşenlerindendir. JTable bileşenini anlatırken çok boyutlu
dizilere benzetebileceğimizi söylemiştik. Bu bileşeni ise tek boyutlu bir diziye
benzetmemiz mümkündür. Elemenalarıindis değerleriyle eşleyerek saklar.
JList bileşeni üzerinde işlemler genelde eleman seçimleriyle
ilgilidir. JTable bileşeninin iki olay tetiklediğini söylemiştik bunlar; eleman
değiştirme olayı ve eleman seçim olayı idi. Bu bileşenimizde işlemler eleman
seçimleriyle ilgili olduğu için bileşenimiz sadece ListSelectionListener olayını
tetikler.
JList bileşeni üzerinde, varsayılan olarak birden fazla seçim yapmanız
mümkündür. Bu durumu değiştirmek için daha önceki dersimizde
kullandığımız gibi setSelectionModel() metodunu kullanabiliriz.
Metodumuzun genel yapısı şu şekildedir:
void setSelectionModel(int
1
secimTipi)
Metodumuzda
belirttiğimiz secimTipi parametresi ListSelectionModel altındaki üç değerden
biri olabilir. Bunlar;

SINGLE_SELECTION

SINGLE_INTERVAL_SELECTION

MULTIPLE_INTERVAL_SELECTION
JList oluşturulduktan itibaren varsayılan
olarak MULTIPLE_INTERVAL_SELECTION değeri gelir. Bu seçim tipi
kullanıcının birden fazla aralıkta öğe seçebilmesini sağlar (çoklu
seçim).SINGLE_INTERVAL_SELECTION ise; kullanıcının bir öğeler
aralığı seçebilmesini sağlar. SINGLE_SELECTIONile sadece tek bir eleman
seçilebilir. JList bileşenini ve olaylarını daha iyi anlayabilmek için bir örnek
yapalım.
1 //JListOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import javax.swing.*;
5 import javax.swing.event.*;
6
7 public class JListOrnegi extends JFrame implements
8 ListSelectionListener
9 {
10 JList liste;
11 JLabel etiket1;
12
13 // uygulama başlatılıyor
14 public static void main(String[] args)
15 {
16
EventQueue.invokeLater(
17
new Runnable()
18
{
19
public void run()
20
{
21
try
22
{
23
JListOrnegi cerceve = new JListOrnegi();
24
cerceve.setVisible(true);
25
} catch (Exception e)
26
{
27
e.printStackTrace();
28
}
29
}
30
});
31 }
32 // bileşenler yapılandırılıyor.
33 public JListOrnegi()
34 {
35
super("JList Örneği");
36
Container con = getContentPane();
37
setLayout(new FlowLayout());
38
// container nesnesi oluşturup yerleşim tipimizi belirledik
39
40
String[] veriler = {"Edirne", "İstanbul", "Kırıkkale", "İzmir",
41
"Trabzon", "Hatay", "Gaziantep", "Malatya", "Giresun"};
42
// listemiz içerisinde gösterilecek verileri ekledik
43
44
liste = new JList<String>(veriler);
45
con.add(liste);
46
liste.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
47
liste.addListSelectionListener(this);
48
/* listemizi oluşturduk, seçim tipini belirledik ve
49
* dinleyici ekledik. */
50
51
etiket1 = new JLabel();
52
53
54
55
56
57
58
59
60
61
62
63
64
65}
con.add(etiket1);
setSize(350, 210);
setVisible(true);
}
@Override
public void valueChanged(ListSelectionEvent ie)
{
int indis = liste.getSelectedIndex();
String veri = (String) liste.getSelectedValue();
etiket1.setText(indis + ". indisdeki veri: " + veri);
}
Yapılandırıcı metodumuz içerisinde yerleşim tipimizi belirledikten
sonra JList bileşenimiz içerisinde gösterilecek verileri oluşturduk. Daha
sonrasında listemizi yaratıp bu elemanları referans listemize
ekledik.JList yapımızı oluştururken diğer bileşenlerden farklı olarak bu
bileşenimizde içerisine eklenecek veri tipini de belirttik. Seçim
tipimizi SINGLE_SELECTION olarak belirledikten sonra listemize
bir ListSelectionListenerdinleyicisi ekledik. Olayımız her eleman değiştiğinde
tetiklenecektir. Olayımız içerisinde önce seçili indisdeğerini daha sonra
elemanı bulduk ve JLabel bileşenimizin yardımıyla bunları ekranda gösterdik.
Ders 152 - JScrollPane
JScrollPane, diğer bileşenleri kaydırmak için oluşturulmuş
bir swing bileşenidir.
Çerçevemize sığmayanbileşenleri JScrollPane bileşenimize eklediğimizde
ekranda çubuklar belirir ve biz bu çubuklar sayesinde bileşenimizin ekrana
sığmayan diğer kısmını da görebiliriz.Bu bileşen swing bileşenleri arasındaki
anlaşılması en basit olanıdır. Yapılandırıcı metodu aşağıdaki gibidir.
1
JScrollPane (Component bilesen)
JScrollPane bileşenini kullanmak için bu bileşenimizi oluştururken parametre
olarak ekrana sığmayan bileşeni veririz. JScrollPane ekrana sığmayan bileşen
için otomatik olarak kaydırma çubukları oluşturacaktır.
Bu konuyu daha iyi anlamak için bir örnek yapalım:
1 //JScrollPaneOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import javax.swing.*;
5 import javax.swing.event.*;
6
7 public class JScrollPaneOrnegi extends JFrame implements
8 ListSelectionListener
9 {
10
JList liste;
11
JLabel etiket1;
12
13
// uygulama başlatılıyor
14
public static void main(String[] args)
15
{
16
EventQueue.invokeLater(
17
new Runnable()
18
{
19
public void run()
20
{
21
try
22
{
23
JScrollPaneOrnegi cerceve = new JScrollPaneOrnegi();
24
cerceve.setVisible(true);
25
} catch (Exception e)
26
{
27
e.printStackTrace();
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 }
}
}
});
}
// bileşenler yapılandırılıyor.
public JScrollPaneOrnegi()
{
super("JScrollPane Örneği");
Container con = getContentPane();
setLayout(new FlowLayout());
// container nesnesi oluşturup yerleşim tipimizi belirledik
String[] veriler = {"Edirne", "İstanbul", "Kırıkkale", "İzmir",
"Trabzon", "Hatay", "Gaziantep", "Malatya", "Giresun"};
// listemiz içerisinde gösterilecek verileri ekledik
liste = new JList<String>(veriler);
con.add(liste);
liste.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
liste.addListSelectionListener(this);
/* listemizi oluşturduk, seçim tipini belirledik ve
* dinleyici ekledik. */
JScrollPane cubuk = new JScrollPane(liste);
con.add(cubuk);
etiket1 = new JLabel();
con.add(etiket1);
setSize(350, 210);
setVisible(true);
}
@Override
public void valueChanged(ListSelectionEvent ie)
{
int indis = liste.getSelectedIndex();
String veri = (String) liste.getSelectedValue();
etiket1.setText(indis + ". indisdeki veri: " + veri);
}
Ekran çıktısı:
Bir önceki bileşen için yaptığımız örneğe bu sefer JScrollPane bileşenini
uyguladık. JScrollPanebileşenimize parametre olarak JList bileşenimizi verdik
ve sonuç olarak JScrollPane bize kendi oluşturduğu kaydırma çubuklarını
verdi.
Ders 153 - JTabbedPane
JTabbedPane, genel olarak bir sekmeli pano bileşenidir. Birden fazla
sekmeler arasında değişik panolar arasında tutabilir. Bu bileşen üzerinde
sekmelere tıklamamız durumunda tıklanılan sekmenin pano içeriği görünür
duruma gelecek, diğer bölümler gizlenecektir. Bu bileşene sekme ekleyebilmek
için addTab()metodunu kullanırız. addTab() metodunun genel yapısı
aşağıdaki gibidir:
void addTab (String sekmeAdi, Component
1
eklenecekBilesen)
İlk parametre sekmenin adını belirler, ikinci parametre ise sekmeye eklenecek
bileşeni belirler. Sekmeye ekleyeceğimiz bileşen
çoğunlukla JPanel olacaktır. JPanel birçok bileşeni bir arada tutabilmemizi
sağlayan bir bileşendir.
Şimdi konuyu daha iyi anlayabilmek için bir örnek yapalım. Aşağıdaki örnek
daha önce JTable bileşeninde yaptığımız örneğin JTabbedPane bileşenine
uyarlanmış hali olacaktır.
1 //JScrollPaneOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4 import javax.swing.*;
5
6 public class JTabbedPaneOrnegi extends JFrame
7 {
8
// uygulama başlatılıyor
9
public static void main(String[] args)
10
{
11
EventQueue.invokeLater(
12
new Runnable()
13
{
14
public void run()
15
{
16
try
17
{
18
JTabbedPaneOrnegi cerceve = new
19 JTabbedPaneOrnegi();
20
cerceve.setVisible(true);
21
} catch (Exception e)
22
{
23
e.printStackTrace();
24
}
25
}
26
});
27
}
28
// bileşenler yapılandırılıyor.
29
public JTabbedPaneOrnegi()
30
{
31
super("JTabbedPane Örneği");
32
Container con = getContentPane();
33
34
JTabbedPane sekmeliPano = new JTabbedPane();
35
sekmeliPano.addTab("İl", new ilPanel());
36
sekmeliPano.addTab("Plaka Kodu", new plakaPanel());
37
sekmeliPano.addTab("Bölge", new bolgePanel());
38
con.add(sekmeliPano);
39
// panomuzu oluşturduk ve sekmelerini ekledik
40
41
setSize(350, 250);
42
setVisible(true);
43
}
44
45
// illeri görüntüleyeceğimiz panel
46
public class ilPanel extends JPanel
47
{
48
public ilPanel()
49
{
50
String[] veriler = {"Edirne", "İstanbul", "Kırıkkale", "İzmir",
51
"Trabzon", "Hatay", "Gaziantep", "Malatya", "Giresun"};
52
JList liste = new JList<String>(veriler);
53
add(liste);
54
// listemize verileri ekledik ve panelimize listeyi ekledik
55
56
JScrollPane cubuk = new JScrollPane(liste);
57
add(cubuk);
58
}
59
}
60
61
// plakaları görüntüleyeceğimiz panel
62
public class plakaPanel extends JPanel
63
{
64
public plakaPanel()
65
{
66
String[] plaka = {"22", "34", "71", "35", "61", "31", "37", "44",
67 "28"};
68
JList liste = new JList<String>(plaka);
69
add(liste);
70
// listemize verileri ekledik ve panelimize listeyi ekledik.
71
72
JScrollPane cubuk = new JScrollPane(liste);
73
add(cubuk);
74
}
75
}
76
77
// bilgileri görüntüleyeceğimiz panel
78
public class bolgePanel extends JPanel
79
{
80
public bolgePanel()
81
{
82
JComboBox combo = new JComboBox();
83
combo.addItem("Marmara");
84
combo.addItem("Ege");
85
combo.addItem("Karadeniz");
86
combo.addItem("Güney Doğu Anadolu");
87
combo.addItem("Doğu Anadolu");
88
combo.addItem("Akdeniz");
89
combo.addItem("İç Anadolu");
90
91
92
add(combo);
}
}
}
Örneğimiz genel JTabbedPane kullanımını görmek içindir. Örneğimizde
yapılandırıcı metodumuz içerisindeaddTab() metodu ile sekmelerimizi ve
bunlar içerisine panolarımızı ekledik. İlk parametremiz sekme ismi için ikinci
paremetremiz ise, sekmeye ekleyeceğimiz bileşendir. Bileşenlerimizi
ekledikten sonra bileşenlerimizi yapılandıracağımız sınıfları yazdık ve işlemi
sonlandırdık. Tüm bu işlemleri yaptıktan sonra uygulamamızın ekran çıktısı,
yukarıdaki şekildeki gibi olacaktır.
Ders 154 - JTree
JTree bileşeni, verilerin hiyerarşik bir biçimde gözükmesini sağlayan bir
görsel bileşendir. Bu bileşen sayesinde kullanıcı verileri hiyerarşik bir biçimde
görüntüleyebilir.
JTree bileşeninin en çok kullanılan yapılandırıcı metodları aşağıdaki gibidir:
1
JTree (Object veri[])
2
JTree (Vector v)
3
4
JTree (TreeModel newModel)
JTree (TreeNode dugum)
İlk yapılandırıcı ile JTree bileşenimizin hiyerarşisi veri dizisinin elemanları
alınarak oluşturulur. İkinci yapılandırıcı ile v vektörü, ağacımızın yapısını
oluşturur. Üçüncü yapılandırıcı da daha önceden tanımlanan bir ağaç modeli
referans verilerek ağacımızın dalları oluşturulur. Dördüncü yapılandırıcı da ise
kök düğümüdugum olan ağaç JTree bileşenimizin verilerini oluşturur.
JTree bileşeninin kendine has bazı olayları vardır. Bu olaylar ve olayların
tetiklendiği durumlar aşağıdaki gibidir.

TreeExpansionEvent: Ağaç genişlediğinde veya daraltığında
tetiklenir.

TreeModelEvent: Ağacın verileri veya yapısı değiştiğinde tetiklenir.

TreeSelectionEvent: Ağacın bir elemanı veya düğümü seçildiğinde
tetiklenir.
Şimdi bu konuyla ilgili bir örnek yapalım.
1 //JTreeOrnegi.java - 25.04.2014
2
3 import java.awt.*;
4
5 import javax.swing.*;
6 import javax.swing.event.*;
7 import javax.swing.tree.*;
8
9 public class JTreeOrnegi extends JFrame
10 {
11
JLabel etiket;
12
13
// uygulama başlatılıyor
14
public static void main(String[] args)
15
{
16
EventQueue.invokeLater(
17
new Runnable()
18
{
19
public void run()
20
{
21
try
22
{
23
JTreeOrnegi cerceve = new JTreeOrnegi();
24
cerceve.setVisible(true);
25
} catch (Exception e)
26
{
27
e.printStackTrace();
28
}
29
}
30
});
31
}
32
// bileşenler yapılandırılıyor.
33
public JTreeOrnegi()
34
{
35
super("JTree Örneği");
36
Container con = getContentPane();
37
setLayout(new FlowLayout());
38
// container nesnesi oluşturup yerleşim tipimizi belirledik
39
DefaultMutableTreeNode
40
agacKoku, altKok1, altKok2, eleman1, eleman2, eleman3, eleman4,
41 eleman5;
42
agacKoku = new DefaultMutableTreeNode("Ana Kök");
43
// örneğimiz için bir ağaç kökü oluşturduk
44
45
altKok1 = new DefaultMutableTreeNode("1. Alt Kök");
46
agacKoku.add(altKok1);
47
altKok2 = new DefaultMutableTreeNode("2. Alt Kök");
48
agacKoku.add(altKok2);
49
// ağacımız için alt kökler oluşturduk ve bu kökleri ağacımıza ekledik
50
51
eleman1 = new DefaultMutableTreeNode("1. Kök 1. Eleman");
52
eleman2 = new DefaultMutableTreeNode("1. Kök 2. Eleman");
53
altKok1.add(eleman1);
54
altKok2.add(eleman2);
55
eleman3 = new DefaultMutableTreeNode("2. Kök 1. Eleman");
56
eleman4 = new DefaultMutableTreeNode("2. Kök 2. eleman");
57
eleman5 = new DefaultMutableTreeNode("3. Kök 3. Eleman");
58
altKok2.add(eleman3);
59
altKok2.add(eleman4);
60
altKok2.add(eleman5);
61
// oluşturduğumuz elemanlarımızı ağacımıza yerleştirdik
62
JTree ornekAgac = new JTree(agacKoku);
63
etiket = new JLabel("Lütfen apacın bir alanını genişletin veya " +
64
"daraltın");
65
66
// ağacımıza genişleme olayını ekledik
67
ornekAgac.addTreeExpansionListener(new TreeExpansionListener()
68
{
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
}
90 }
@Override
public void treeExpanded(TreeExpansionEvent arg0)
{
// ağaç genişlediğinde çalışır
etiket.setText(arg0.getPath().toString() + " alanı genişledi.");
}
@Override
public void treeCollapsed(TreeExpansionEvent arg0)
{
// ağaç daraltıldığında çalışır
etiket.setText(arg0.getPath().toString() + " alanı daraltıldı.");
}
});
con.add(ornekAgac);
con.add(etiket);
setSize(350, 250);
setVisible(true);
// bileşenlerimizi formumuza ekledik.
Örneğimizde JTree bileşenimizi oluşturmadan önce bileşenimizin sahip olacağı
kökü ve alt dalları belirledik. Daha sonra oluşturduğumuz bu
ağacı JTree bileşenimize parametre olarak gönderdik. Bu
kısımdaJTree bileşenimizin içeriğini belirlemiş olduk. Daha sonraki kısımda
ise bileşenimize genişleme veyadaraltmayı kontrol
eden TreeExpansionListener ekledik.
Listener sınıfımızın bize sağladığı metodları kullanarak, ağacımızın genişleyen
veya daralan kollarınıJLabel nesnemize aktardık.
Ders 155 - Layout (Yerleşim Düzenleri)
Layout'lar Java'da görsel uygulamalarda bileşenlerin yerini belirlemek için
kullandığımız bileşenlerdir. Çoğu zaman layout'ları bileşenlerin form
üzerinde daha düzenli durması için kullanırız. Layout üzerindeki bileşen form
büyüyüp küçülse bile, layout'a göre şekillenir. Yani pencere büyüyüp
küçülmesinden dolaylı olarak etkilenir. Görsel bileşenler form üzerine
ekleneceği zaman layout olmadığı durumda, ekleneceği yerin x ve ynoktası
girilerek eklenir. Layout bizi bu dertten kurtarır. Layout bileşenleri form
üzerine layout tipine göre düzenle yerleştirir.
GRIDLAYOUT
Bileşenleri küçük dikdörtgenler içerisinde düzenli bir biçimde tutmaya yarar.
İçerisine eklenen her bileşenfarklı bir dikdörtgen içerisinde tutulur. Eklenen
bileşenlerin hepsinin aynı boyutta olmasını sağlar ve bileşenleri
düzenler. GridLayout üzerindeki bileşenler aşağıdaki örnekteki gibi gözükür:
1
//GridLayoutOrnegi.java - 25.04.2014
2
3
import java.awt.*;
4
5
public class GridLayoutOrnegi
6
{
7
public static void main(String[] args)
8
{
9
Frame cerceve = new Frame();
10
// çerçeve oluşturduk.
11
cerceve.setLayout(new GridLayout(3, 3));
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// çerçevenin layoutunu belirledik
cerceve.add(new Button("1"));
cerceve.add(new Button("2"));
cerceve.add(new Button("3"));
cerceve.add(new Button("4"));
cerceve.add(new Button("5"));
cerceve.add(new Button("6"));
cerceve.add(new Button("7"));
cerceve.add(new Button("8"));
cerceve.add(new Button("9"));
// çerçevemize bileşenleri ekledik
cerceve.setBounds(100, 100, 400, 300);
cerceve.setVisible(true);
// çerçevemizin boyutunu belirledik ve çerçevimizi görünür
yaptık
}
}
BORDERLAYOUT
Bu yerleşim tipi en çok kullanılan yerleşim tiplerindendir. Bileşenleri çerçeveyi
bölgelere ayırır ve bu belirlenen bölgelere bileşenleri düzenli bir biçimde ekler.
Genelde çerçeveyi kuzey, güney, doğu, batı vemerkez olmak üzere beşe ayırır
ve bileşenleri bu bölgelerden istenilen birine ekler. BorderLayout üzerinde
bileşenler aşağıdaki örnekteki gibi gözükür.
1
//BorderLayoutOrnegi.java - 25.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.awt.*;
public class BorderLayoutOrnegi
{
public static void main(String[] args)
{
Frame cerceve = new Frame(); // çerçeve belirledik
cerceve.setLayout(new BorderLayout());
// yerleşim tipi belirlendi
cerceve.add(new Button("Kuzey"),
BorderLayout.NORTH);
cerceve.add(new Button("Güney"),
BorderLayout.SOUTH);
cerceve.add(new Button("Doğu"), BorderLayout.EAST);
cerceve.add(new Button("Batı"), BorderLayout.WEST);
cerceve.add(new Button("Merkez"),
BorderLayout.CENTER);
// butonlar eklendi
cerceve.setBounds(100, 100, 400, 300);
cerceve.setVisible(true);
// çerçevemizin boyutunu belirledik ve çerçevimizi görünür
yaptık
}
}
FLOWLAYOUT
Bu yerleşim tipi bileşenleri soldan sağa doğru sırayla ekler. Soldan devam
edecek yer kalmayınca bir alt satırdan tekrar bileşenleri soldan sağa doğru
eklemeye başlar. Bu layout türünün yapılandırıcısına vereceğimiz parametre ile
bileşenlerin sağa, sola veya ortaya yaslı olmasını sağlayabiliriz. Bu
parametreler sınıf içerisinde tanımlı sabitlerdir.
Bu sabitler şöyledir:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

LEFT: Bileşenlerin sola yaslı olmasını sağlar.

RIGHT: Bileşenlerin sağa yaslı olmasını sağlar.

CENTER: Bileşenlerin merkeze yaslı olmasını sağlar.

LEADING: Bileşenlerin soldan sağa eklenilmesini sağlar.

TRAILING: Bişelenlerin sağdan sola eklenilmesini sağlar.
//FlowLayoutOrnegi.java - 25.04.2014
import java.awt.*;
public class FlowLayoutOrnegi
{
public static void main(String[] args)
{
Frame cerceve = new Frame();
cerceve.setLayout(new
FlowLayout(FlowLayout.CENTER));
// çerçeve tanımlandı ve tipi belirlendi
cerceve.add(new Button("Button1"));
cerceve.add(new TextField("Metin Alanı 1"));
cerceve.add(new Button("Button2"));
cerceve.add(new TextField("Metin Alanı 2"));
cerceve.add(new Button("Button3"));
cerceve.add(new TextField("Metin Alanı 3"));
cerceve.add(new Button("Button4"));
cerceve.add(new TextField("Metin Alanı 4"));
cerceve.setBounds(100, 100, 600, 100);
cerceve.setVisible(true);
// çerçevemizin boyutunu belirledik ve çerçevimizi görünür
yaptık
}
}
GRIDBAGLAYOUT
GridBagLayout, çok fazla bileşen kullandığımızda karmaşıklığı ortadan
kaldırmak için kullanılır.GridBagLayout, GridBagConstrains sınıfı ile her
bileşenin ayrı ayrı nasıl yerleşeceğini belirler.
1 //GridBagLayout.java - 25.04.2014
2
3 import java.awt.*;
4
5 public class GridBagLayoutOrnegi
6 {
7
public static void main(String[] args)
8
{
9
Frame cerceve = new Frame();
10
cerceve.setLayout(new GridBagLayout());
11
GridBagConstraints g = new GridBagConstraints();
12
g.fill = GridBagConstraints.CENTER;
13
// bileşenleri belirli kriterlere göre çerçevemize ekleyecek nesneyi
14 oluşturduk
15
g.weightx = 1;
16
g.weighty = 0;
17
// bileşenlerin arasında kaç birim boşluk bulunacağını bu değişkenlerle
18 belirliyoruz.
19
g.gridx = 1;
20
g.gridy = 1;
21
// bileşenleri düzlemde nereye ekleyeceğimizi bu bileşenlerle
22 belirliyoruz
23
// örneğin bu bileşen X düzleminde 1 Y düzleminde 1 olan yere
24 yerleşir
25
cerceve.add(new Button("5"), g);
26
g.gridx = 0;
27
g.gridy = 0;
28
cerceve.add(new Button("1"), g);
29
g.gridx = 2;
30
g.gridy = 0;
31
cerceve.add(new Button("3"), g);
32
g.gridx = 1;
33
g.gridy = 0;
34
35
36
37
38
39
40
cerceve.add(new Button("2"), g);
g.gridx = 2;
g.gridy = 1;
g.anchor = GridBagConstraints.LINE_START;
cerceve.add(new Button("4"), g);
cerceve.setBounds(100, 100, 400, 300);
cerceve.setVisible(true);
}
}
DİĞER LAYOUT ÖRNEKLERİ
Yukarıda en çok kullanılan layout tiplerini açıkladık. Diğer layout tipleri ise,
yukarıdaki layout tipleri kadar kullanılmazlar. Bu layout tipleri ve görevleri
şöyledir:

CardLayout: Bileşenleri çerçeveye birer kart olarak ekledik. Aynı
anda sadece bir kart görünür durumda olabilir. Yani bu yerleşim
tipiyle bazı bileşenlerin bazı anlarda görünmesini sağlarken bazı
bileşenlerin gizlenmesini sağlayabiliriz.

BoxLayout: GridLayout yerleşim düzenini anlatırken bileşenlerin
hepsinin aynı boyutta olmasını sağladığını söylemiştik. BoxLayout,
çoğu özelliğiyle GridLayout'a benzemesine rağmen bu
özelliğiyleGridLayout'tan ayrılır. Ayrıca GridLayout'a oranla daha
fazla özelliğe sahiptir.
Ders 156 - Veritabanı Kavramına Giriş
Yazılıma yeni başlayanlar genelde küçük programlar yaparak programlamaya
adım atarlar. C ile program yazanlar ilk başta Structure içerisine kayıt eklerler
daha sonra bilgileri dizilerde tutup, tekrar elde ederler. Farklı programlama
dilleri öğrendikçe büyük projeler yapma isteği sonucunda veritabanına ihtiyaç
duyulur.
Veritabanı, geniş depolama kapasitesi olan, verileri hızlı bir şekilde depolayıp
yine hızlı bir şekilde elde etmeye yarayan, verileri sistematik bir şekilde tutan,
farklı türdeki verileri bünyesinde bulunduran, yönetilebilir, güncellenebilir bir
yapıdır.
Veritabanları, veri modelleri ile saklanırlar. Bu veri modelleri birkaç farklı
bölümde incelenir. Bunlardan bazıları:

Nesneye Yönelik Model

Ağ Modeli

Hiyararşik Model

Varlık-İlişki Modeli
Bu modellerden en çok kullanılanı ilişkisel modeldir. Bu ilişkisel modelde
veriler tablolar halinde tutulur. Diyelim ki bir öğrenci not sistemi yazmak
istiyoruz. Bunun için bir öğrenci üzerinden gidersek öğrenci bilgilerini
tutan Öğrenci tablosu, öğrenci notlarını tutan Notlar tablosu, hoca
isimlerini tutan Hocalar tablosu,dersleri tutan Dersler tablosu gibi birçok
tablo oluşturmamız gerekir. Daha sonra bu tabloları birbiri
ileilişkilendirmek gerekir.
Bu tablolardaki bilgilere kayıt denir. Her tabloda birçok sütun bulunur. Örnek
olarak bir veritabanı tablosuve bu tablo içerisindeki kayıtları gösterelim.
Yukarıda bir tablomuz var. Bu tablomuzun adı Öğrenciler olsun.
Bu Öğrenciler tablosunda OgrenciNo,OgrenciAd, OgrenciSoyad, OgrenciB
olum alanlarımız var. Bunlara sütun denir. Tablodaki her bir satırdaki bilgilere
de kayıt denir.
Tablomuzda öğrenci numarası Primary Key (PK-birincil anahtar) olarak
ayarlanmıştır. Nedir bu Primary Key, onu açıklayalım.
Ülkemizde her kişinin T.C. numarası birbirinden farklıdır. Sistemlerde
bu T.C. numarası girildiğinde tek bir kişi gelir. Fakat bir ad veya
bir soyad girdiğimizde, birçok kayıt gelecektir. İşte bu T.C. numarası Primary
Keyolarak tanımlanmıştır. Yani bu alanda birden fazla kayıt olamaz. Biz de
aynı Öğrenci numarasına sahip bir başka kişi olmasın diye bu alanı Primary
Key olarak tanımladık. Örneğimizde gözükmese de bu alan Primary
Key olarak tanımlanmıştır. Tablodaki bilgileri, girilmiş şekilde gösterdiğimiz
için Primary Key alanını göremedik. Aşağıdaki şekilde Primary Key alanı
daha net görünmektedir.
Yukarıdaki şekil, tablodaki alanları tanımladığımız yeri gösterir. Her alan için
boyut, tip gibi özellikler girilir.
Ders 157 - Veritabanı Yönetim Sistemleri (VTYS)
Önceki dersimizde veritabanı kavramını anlatmıştık. Peki, bu verilerimizi
nereye kaydediyoruz? Veritabanını ne üzerinden yönetiyoruz? Burada VTYS
kavramı karşımıza çıkıyor.
Veritabanlarını oluşturmak, oluşturulan veritabanları
üzerinde silme, ekleme, arama gibi işlemler yapan, veritabanındaki tüm
ihtiyaçları gideren yazılım sistemine veritabanı yönetim sistemi (database
management system) denir. Veritabanı yönetim sistemi, veritabanımızı diğer
kullanıcılara açar. Veritabanı yönetim sistemi ile veritabanımızın tüm
gereksinimlerini karşılarız. Bunu şöyle açıklayalım.
Kullanıcı adı ve şifre isteyen bir online uygulamaya bir giriş yapamıyorsak
bunu VTYS engellediği için yapamıyoruz demektir. İznimiz olan bir
uygulamaya şifremiz ile giriş yaptık diyelim. Sistemdeki her bilgiyi
göremiyorsak, bu yine VTYS'de bize izin tanımlanmadığı içindir.
Peki, bu VTYS'yi kim yönetiyor? Veritabanı yönetim sistemini kullanan
deneyimli kişilere Veritabanı Yöneticisi denir. Bu kişiler, VTYS kullanarak
veritabanına girebilecek kişileri yönetir, veritabanına tablo veya kayıt ekleyip
çıkarabilir, veritabanına giren kişilerin izinlerini yönetebilir ve bunun dışında
birçok işi yapabilir. O yüzden bu kişilerin deneyimli olmaları gerekir.
VTYS'yi anlattık. Bu veritabanı yönetim sistemlerine örnek verecek olursak;
bunlar veritabanını yönetmeyi sağlayan MySQL, Oracle, Microsoft SQL
Server, Postgresql, Apache, Access gibi sistemlerdir. Bunlar en bilinenleridir.
Her biri ihtiyacımıza göre farklı yerlerde kullanılır. Biz
derslerimizde MySQL veritabanını kullanacağız.
Ders 158 - JDBC Tanımı
JDBC (Java Database Connectivity), Java geliştiricilerine Java kodu üzerinden
veritabanı yönetim sistemlerine erişim imkânı sağlayan bir Java arayüzüdür.
Bu arayüz sayesinde Java uygulamalarımız üzerinden herhangi bir veritabanına
bağlanıp veritabanından veri elde edebiliriz.
JDBC, 2 katmandan oluşur. Bu yapının en üstünde JDBC API'si bulunur.
Yazdığımız SQL komutlarını JDBC API, alt katmanında bulunan sürücü
yöneticisine gönderir. Bu sürücü yöneticisi, veritabanları ile iletişime geçer ve
dönen sonuçları JDBC API'ye gönderir.
Peki, JDBC arayüzünü kullanmak için neler gereklidir? Bu arayüzü kullanmak
için aşağıdaki öğeler gerekmektedir:

Veri tabanı yönetim uygulaması (MySQL, MSSQL, ORACLE vb.)

Java Database Server

SQL Sorgulama dil bilgisi

Veritabanı uygulaması ve Java uygulamamız arasındaki bağlatıyı
sağlayacak kod
Biz derslerimizde MySQL veritabanı yönetim aracını kullanacağız.
Yukarıda bahsettiğimiz gibi JDBC için SQL sorgulama dilini de
bilmeyi gerektiriyor. Bir sonraki dersimizde bu sorgulama dilinin
komutlarına değineceğiz. Daha sonraki dersimizde ise
uygulamalarımızda kullanacağımız veritabanı yönetim aracı
olanMySQL'in kurulumuna geçelim.
Ders 159 - Temel SQL Komutları
VTYS için birçok sistemden bahsettik. Bu sistemler ile veritabanındaki
kayıtları her türlü kontrol edebiliyor ve veritabanı üzerindeki ayarlamaları
yapıyorduk. Peki, programımızdan bu veritabanına ulaşıp veri eklemeyi,
silmeyi, güncellemeyi, tablolar oluşturmayı nasıl yapacağız?
Çoğu veritabanı sistemlerinde SQL dili kullanılır. Programımızdan veya
MySQL arayüzümüzden SQL komutlarını kullanarak veritabanımız üzerinde
işlemler yapabiliriz. Şimbi bu temel komutları görelim.
SELECT - WHERE - LIKE KOMUTLARININ KULLANIMI
SELECT komutu, veritabanımızdaki kayıtları getirir. Genel kullanımı
aşağıdaki gibidir.
1
SELECT * FROM tablo_adi
Burada * işaretini kullanırsak tüm sütunları getir anlamına
gelir. FROM kelimesinden sonra ise tablo adımız yazılır. Bir örnek verirsek:
1
SELECT * FROM Urunler
Bu sorgu, Urunler tablosundaki tüm kayıtları getirir. Fakat biz her kaydı değil
de belirli bir koşula bağlı olarak kayıtları getirmek istiyorsak, ne yapmalıyız?
Bunun için kullanmamız gereken kelime WHERE kelimesidir. Bu kelimeden
sonra koşulumuz yazılır. Aşağıdaki komutu inceleyelim.
1
SELECT * FROM Urunler WHERE fiyat>5000
Bu komut, Urunler tablosundan, fiyatı 5000'den büyük olan kayıtları getirir.
Buraya kadar gösterdiğimiz komutlarda, bir kaydın tüm bilgilerini getiriyordu.
Eğer biz koşulu sağlayan kayıtların sadece fiyat ve miktar bilgilerinin
getirilmesini istiyorsak, yazacağımız komut aşağıdaki gibidir:
1
SELECT fiyat, miktar FROM Urunler Where fiyat>5000
Yukarıdaki komut, fiyatı 5000'den büyük olanların
sadece fiyat ve miktar bilgilerini döndürür.
Bir başka ihtimali de düşünelim. Tablomuzda x markalı bir ürünü getirsin
istiyorsak ne yapmamız gerekir? Bir önceki örnekte WHERE ifadesinden sonra
bir sayı karşılaştırdık. Fakat şimdi String veya Char bir ifade ile filtreleme
yapmak isteyelim. Bunun için yazmamız gereken komut:
1
SELECT * FROM Urunler WHERE marka = 'x'
Yukarıdaki ifade dediğimiz gibi Urunler tablosunda markası x'e eşit olan tüm
kayıtları getirir.
Şimdi farklı bir tablo üzerinde işlem yapalım ve bu sefer WHERE ifadesinin
başka bir özelliğini kullanalım.
SELECT * FROM Ogrenci WHERE ogrCinsiyet = 'E' AND
1
ogrYas = 21
Burada WHERE ifadesinden sonra 2 şart koyduk. Hem cinsiyeti E olan hem
de yaşı 21 olan öğrencilerintüm bilgilerini getirmesini
istedik. WHERE ifadelerinde birden fazla koşul kullanılabilir.
WHERE ifadesi ile kullanılan bir ifade daha vardır. WHERE ile kayıtları
filtreleyebiliyorduk. Aynı şekildeLIKE ifadesiyle de kayıtlar filtrelenir. Şimdi
bir örnek verelim:
SELECT * FROM Urunler WHERE UrunAdi LIKE '%A%' AND
1
UrunFiyat>1000
Yukarıdaki sorguda Urunler tablosundan, ürün adında A harfi
bulunan kayıtlar ve fiyatı 1000'den büyük kayıtlar getirilir. Hem ilk
şartı hem de ikinci şartı sağlayan kayıtlar getirilir. Aşağıdaki bir başka sorguyu
inceleyelim.
SELECT * FROM Urunler WHERE UrunMarka LIKE
1
'%A'
Yukarıda da Urunler tablosunda ürün markası A harfi ile biten kayıtlar
getirilir. Eğer T% yapsaydık, T harfi ile başlayan kayıtlar
getirilirdi. LIKE ifadesinin kullanım şekli böyledir. Bir harf ile başlayan, biten
veya içerisinde o harf bulunan kayıtları filtrelemek için kullanılır.
SELECT, WHERE, LIKE komutlarının kullanılışı temel olarak bu şekildedir.
Örnekler çoğaltılabilir. Biz örneklerimizin anlaşılması açısından temel olanları
inceleyeceğiz. Veritabanı, başlı başına bir konudur.
INSERT KOMUTU İLE KAYIT EKLEME
INSERT komutu, tablolara kayıt eklemeye yarar. Genel kullanımı şu
şekildedir:
INSERT INTO tablo_adi VALUES (veri_1, veri_2,
1
veri_3)
Yukarıda tablo_adi kısmına tablomuzun adını yazıyoruz. VALUES'ten sonra
ise ekleyeceğimiz verilerigiriyoruz.
Örnek verirsek;
INSERT INTO Urunler VALUES (500, 'Bilgisayar',
1
1500)
Yukarıda Urunler adlı tablomuzun 3 sütunu olduğunu farz ediyoruz. Bu 3
sütunun da miktar, ad ve fiyatolduğunu düşünelim. VALUES'ten sonra bu
alanımıza sırayla verileri gönderiyoruz ve kaydımız ekleniyor.
INSERT ile kayıt eklemenin başka bir yolu da şudur:
INSERT INTO Kisiler (KisiAd, KisiSoyad, KisiMeslek) VALUES ('Okan', 'Bilke',
1
'Ogrenci')
Bu şekilde de ekleme yapabiliriz. Böyle ekleme yapmanın faydası, eklediğimiz
verilerin hangi sütuna eklendiğini bilmemizdir.
DELETE KOMUTU İLE KAYIT SİLME
DELETE komutu ile tablomuzdan verileri silebiliriz. Genel kullanımı
aşağıdaki gibidir.
1
DELETE FROM tablo_adi
FROM kelimesinden sonra tablomuzun adı yazılır. Yukarıdaki gibi sorgu
yazarsak, bir şartımız olmadığı için o tablodaki tüm kayıtlar silinir.
Eğer WHERE ile şart ekleyeceksek aşağıdaki gibi bir kullanım da olabilir.
DELETE FROM Urunler WHERE UrunAdi LIKE
1
'%R%'
Urunler tablosundan ürün adında R harfi olan tüm kayıtlar silinir.
UPDATE KOMUTU İLE KAYIT GÜNCELLEME
UPDATE komutu ile tablomuzdaki kayıtları güncelleyebiliriz. Genel kullanım
şeklini bir örnekle açıklayalım.
UPDATE Urunler SET UrunFiyat = '300' WHERE UrunAdi =
1
'Oyuncak'
Burada Urunler tablomuzda Urun adı Oyuncak olan kaydın fiyatını 300
yapıyor.
Sadece bir sütunu değil birden fazla sütunu da güncelleyebiliriz. Bunun için
şöyle bir sorgu örneği gösterelim.
UPDATE Urunler SET UrunFiyat='100' AND UrunStok='50' WHERE
1
UrunAdi='Bilgisayar'
Urun adı Bilgisayar olan kaydın, Stok sayısını 50 ve fiyatını 100 yapıyor.
Burada UrunFiyat, UrunStok, UrunAdi gibi ifadeler, bizim
tablomuzdaki sütunların isimleridir. Tabloda üstün isimlerini nasıl
kaydettiysek, sorgumuzda da o şekilde kullanmalıyız.
Ders 160 - MySQL Kurulumu
MySQL'i kurarak bilgisayarımızda bir MySQL sunucusu kurmuş oluruz ve
verilerimizi bu sunucu üzerinden saklarız.
Veritabanı yönetim aracımızın kurulumuna yönetim aracımızı internette
indirerek başlayalım.
MySQL sunucumuzu yükledik. Fakat burada bilmemiz gereken bir şey daha
var. Programımızda veritabanı ile işlem yapmak istediğimizde bu sunucunun
açık olması gerekir. İster bilgisayarın her açılışta bunu açmasını, istersek de
gerektiğinde açık olmasını ayarlayabiliriz.
Bunun için Bilgisayarım'a sağ tıklayıp Yönet diyoruz.
Karşımıza gelen ekrandan Bilgisayar Yönetimi - Hizmetler ve Uygulamalar Hizmetler kısmına tıklıyoruz ve aşağıdaki gibi bir ekran elde edeceğiz.
Buradan MySQL'in olduğu alana geliyoruz.
MySQL hizmetini çalıştırmak ya da durdurmak için 2 kere
tıklıyoruz. Başlat veya Durdur butonlarıyla hizmeti durdurup başlatabilirsiniz.
Eğer bilgisayarın her açılışında başlamasını istiyorsak, Başlangıç
Türü kısmından otomatik şıkkını seçiyoruz.
Artık MySQL sunucumuz kurulmuş oldu. Veritabanları oluşturulabilir, kayıt
ekleyebilir ve daha birçok işlemleri yapabiliriz. Bu işlemleri komut
istemcisinden yapabiliriz, fakat bir uygulama indirip onun üzerinden yapmak
daha hızlı olacaktır.
Istisnalar:
! MySQL kurulumunda belirlediğiniz kullanıcı
adı ve şifrenizi unutmayın. Veritabanına
bağlanırken bu bilgileri kullanacağız.
Ders 161 - MySQL İçin JDBC Connector
Java üzerinden bir veritabanına bağlanmak için gerekli olan bir şey JDBC
Connector, yani bağlantı nesneleridir. Bunlar, JDBC Driver ile sunucumuz
arasında bağlantıyı kuran bir kütüphanedir. Bu bölümdeMySQL veritabanı
yönetim uygulamasını kullanacağımızı daha önceden belirtmiştik. Şimdi
bir JDBC Connectornesnesini Eclipse ortamına nasıl ekleyebileceğimizden
bahsedelim.
Bu linke tıklayarak MySQL sitesi üzerinden JDBC Driver for MySQL
(Connector/J) nesnesini indiriyoruz. Eclipse üzerinden anlattığımız için
bu mysql connector jar dosyasını Eclipse'de projemize eklemeyi gösterelim.
mysql-connector-java-5.1.30.zip dosyası indikten sonra içerisinde
bulunan mysql-connector-java-5.1.30-bin.jar dosyasını kullanacağız.
1.
İlk yol JRE dizinine atmaktır. Program
Files içerisinde Java klasörünün altında
kullandığımız JREversiyonuna girelim. Bu klasör altında da
sırasıyla lib ve ext klasörlerine girelim ve indirdiğimiz bu mysql
connector nesnemizi buraya atalım.
2.
Diğer yol olarak da projemize ekleyebiliriz. Bunun
için Eclipse üzerinde Project - Properties - Java Build Path - Add
External JARs diyerek bu connector nesnemizi ekleyelim.
Connector nesnemizi bilgisayarımıza kurduktan sonra kod aşamamıza
geçebiliriz. Şimdi Java üzerinden veritabanına bağlantının nasıl olduğunu
görmek için bir örnek yapalım.
1 //databaseOrnek.java - 26.04.2014
2
3 import java.sql.*;
4
5 public class databaseOrnek
6 {
7
public static void main(String[] args)
8
{
9
baglanti();
10
}
11
12
public static void baglanti()
13
{
14
try
15
{
16
Class.forName("com.mysql.jdbc.Driver");
17
// veritabanı tipi
18
Connection connection = DriverManager.getConnection(
19
"jdbc:mysql://localhost:3306/test", "root", "12345");
20
// bağlantı nesnesi
21
Statement state = connection.createStatement();
22
ResultSet sonuc = state.executeQuery("Çalıştırılacak SQL
23 komutu");
24
connection.close();
25
} catch (Exception e)
26
{
27
e.printStackTrace();
28
}
29
}
30 }
Kodumuzda önce hangi tip veritabanına bağlanacağımızı belirttik. Daha
sonra ise bağlantı nesnemizeveritabanı yolu, kullanıcı adı ve kullanıcı
şifremizi vererek oluşturuyoruz. ResultSet nesnesi, veritabanından
çektiğimiz bilgileri tutacak nesnemizdir. executeQuery() metoduna
parametre olarak SQL sorgu komutunu gönderiyoruz ve sorgumuzu
çalıştırıyoruz. Dönen sonucum ResultSet nesnemiz içerisinde oluyor.
Ders 162 - JDBC Bileşenleri
Java da veritabanı uygulamaları yazabilmemiz için bilmemiz gereken bir takım
yazılımsal öğeler vardır. Bunlar veritabanına bağlantı, veritabanına sorgu
gönderme ve veritabanından dönen verileri tutma gibi görevleri üstlenirler.
Bu bileşenler aşağıdaki gibidir:

Connection

Statement

ResultSet
Bu bileşenlerden Statement bileşeni icra ettiği görev bakımından 3'e ayrılır.
Şimdi bileşenlerimizi inceleyemeye başlayalım:
CONNECTION
Veritabanına bağlantı yapmamızı sağlayan bileşendir. Veritabanı ile Java
uygulamamız arasında bir köprükurar. SQL sorguları bu bileşen sayesinde
çalıştırılır ve dönen sonuçlar yine bu bileşen sayesinde bize
döner.Connection bileşeni bağlantıyı oluşturduğu an Statement bileşeni
oluşturulabilir hale gelir.
Veritabanına bağlanabilmek için iki sınıftan yararlanabiliriz.
Bunlar; DriverManager ve DataSource. Biz en çok kullanılan sınıf
olan DriverManager sınıfını kullanacağız. Veritabanına
bir Connection nesnesi oluşturabilmek
için DriverManager sınıfının getConnection() metodunu kullanırız. Bu
metodu kullanabilmemiz için üç parametreye ihtiyacımız vardır.
Bunlar; bağlantı metni, veritabanı kullanıcı adı ve veritabanı kullanıcı
şifresi. Genel bir bağlantı nesnesi aşağıdaki gibidir.
1 //ConnectionOrnek.java - 26.04.2014
2
3 import java.sql.DriverManager;
4 import java.sql.Connection;
5
6 public class ConnectionOrnek
7 {
8
public static void main(String[] args)
9
{
10
try
11
{
12
String baglanti = "jdbc:mysql://localhost:3306/test";
13
// veritabanı adresidir.
14
String kulAdi = "root";
15
String kulSifre = "12345";
16
Connection connection = DriverManager.getConnection(baglanti,
17 kulAdi, kulSifre);
18
// connection nesnesi oluşturuldu, parametreler verildi
19
connection.close();
20
} catch (Exception e)
21
{
22
e.printStackTrace();
23
}
24
}
25 }
Veritabanına bağlantıyı yukarıdaki örnekte olduğu gibi kurabiliriz. Veritabanı
bağlantısıyla işimiz bittiğinde yukarıdaki örnekte olduğu bir
bağlantımızı close() metoduyla kapatmalıyız. Aksi halde veritabanına ikinci kez
ulaşmak istediğimizde hata almamız muhtemel olacaktır
Veritabanına bağlantı için gerekli parametreleri vererek, Connection adında bir
nesne oluşturduk. Bu nesne üzerinden veritabanımıza sorgular göndereceğiz.
STATEMENT BİLEŞENLERİ
Veri tabanı ile bağlantımızı oluşturduktan sonra SQL sorgularını çalıştırabilmek
için Statementbileşenlerine ihtiyacımız vardır. Üç farklı Statement bileşeni
vardır. Bunlar Statement, PreparedStatement veCallableStatement. Şimdi
bu bileşenleri kısaca açıklamaya çalışalım.
STATEMENT
Static olarak oluşturulan bir Statement nesnesidir. Derleme olmaksızın
çalıştırılan en hızlı bileşendir.executeQuery() metoduyla çalıştırılmak
istenen SQL komutu çalıştırılabilir. Bu bileşenin yapısını ve kullanımını
görmek için bir örnek yapalım.
1 //statementOrnek.java - 26.04.2014
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.sql.ResultSet;
import java.sql.Statement;
public class StatementOrnek
{
public static void main(String[] args)
{
try
{
Class.forName("com.mysql.jdbc.Driver");
//JDBC sürücüsünü yükledik
String bagMetni = "jdbc:mysql://localhost:3306/test";
Connection bag = DriverManager.getConnection(bagMetni, "root",
"12345");
// bağlantımızı oluşturduk.
Statement st = bag.createStatement();
/* statement nesnemizi oluşturduk. bag nesnesi üzerinden
* createStatement() metodunu çağırdık. */
String sql = "SELECT * FROM ogrenci";
// sorgu cümlesi oluşturduk
ResultSet sonuc = st.executeQuery(sql);
// SQL sorgumuzu çalıştırdık ve sonuç ResultSet nesnesi yüklendi
bag.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
+
1.
En üst satırda JDBC sürücüsünü yükledik. Konuyu
anlatırken JDBC sürücüsünden bahsetmiştik. Veritabanı ile etkileşime
geçerek dönen sonuçları JDBC API'ye gönderiyordu.
2.
Bağlantı metnini verdik ve Connection nesnesi oluşturduk.
3.
Bu nesne üzerinden createStatement() metodunu çağırdık ve
bunu Statement tipinde bir nesneye atadık. Bu nesne üzerinden
sorguları çalıştıracağız.
4.
Daha sonra sorgu cümlemizi
oluşturduk. Statement tipindeki st nesnesi
üzerinden executeQuery()metodu ile sorgumuzu çalıştırdık ve dönen
değeri ResultSet'e atadık.
5.
Son olarak bağlantımızı kapattık.
PREPAREDSTATEMENT
PreparedStatement bileşeni, ön derlemeden geçirilen Statement bileşenidir.
Çalıştırılacak SQL sorgunuzbirçok kez kullanılacağı
zaman Statement bileşeninden daha iyi performans sunar. Bir sorgu birçok
defa kullanılacaksa, yukarıdaki Statement ile yapacağımız sorgularda her
seferinde bu sorgu derlenir. FakatPreparedStatement ile bir kere derleyip
tekrar tekrar kullanabiliriz. Bu PreparedStatement bileşeninde,
ayrıca SQL sorgusu içerisinde değer girilmesi gereken yerlerde yer tutucu
olarak ? karakteri kullanılmaktadır. Bu bizi karmaşıklıktan bir nebze
uzaklaştırır. Bu bileşenimizin yapısını daha iyi anlamak ve tutucuların nasıl
kullanıldığını görmek için bir örnek yapalım.
1 //PreparedStatementOrnek.java - 26.04.2014
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.PreparedStatement;
6 import java.sql.ResultSet;
7
8 public class PreparedStatementOrnek
9 {
10
public static void main(String[] args)
11
{
12
try
13
{
14
Class.forName("com.mysql.jdbc.Driver");
15
// JDBC sürücüsünü yükledik
16
17
String bagMetni = "jdbc:mysql://localhost:3306/test";
18
Connection bag = DriverManager.getConnection(bagMetni, "root",
19 "12345");
20
// bağlantımızı oluşturduk
21
22
String sql = "UPDATE ogrenci SET ogrAd =? WHERE ogrNo=?";
23
PreparedStatement pSt = bag.prepareStatement(sql);
24
pSt.setString(1, "Sezer"); // ilk ? olan kısma atandı
25
pSt.setInt(2, 3361);
// ikinci ? olan kısma atandı
26
/* PreparedStatement nesnemizi oluşturduk ve
27
* parametrelerimizi nesnemize geçirdik. */
28
29
ResultSet sonuc = pSt.executeQuery();
30
// SQL sorgumuzu çalıştırdık ve sonuc ResultSet nesnesi yüklendi
31
32
bag.close();
33
}
34
catch (Exception e)
35
{
36
e.printStackTrace();
37
}
38
}
39 }
Örneğimizde gördüğünüz gibi bir PreparedStatement bileşeni oluşturduk ve
bu bileşenimize daha önceden yazdığımız SQL komutunu parametre olarak
atadık. Bundan sonraki kısımda ise setString() vesetInt() metotları yardımıyla
SQL komutumuzdaki yer tutucuların olduğu bölgelere parametrelerimizi
geçirdik. Yani sorgumuzda ? olan yerlere değerleri atadık. Bundan sonraki
kısımda ise daha önceden yaptığımız gibiResultSet bileşenimize sonucumuzu
aktardık. Bu sefer ResultSet bileşenine executeQuery() komutuyla sorgu
aktarırken SQL sorgusunu parametre olarak vermediğimize dikkat edelim.
SQL sorgumuzu daha önceden preparedStatement bileşenimize parametre
olarak vermiş oluyoruz.
CALLABLESTATEMENT
CallableStatement bileşeni genellikle depolanmış yordamları (Stored
Procedure) çağırmak için kullanılır. Bu bileşenimize daha önce anlattığımız iki
bileşenin arası diyebiliriz. CallableStatement bileşenleri ön derleme yapılarak
çalıştırılır, fakat yordam veritabanı üzerinde olduğu için tekrar derleme
gerektirmez. Şimdi depolanmış yordamın nasıl çağrıldığını görmek için bir
örnek yapalım.
1
CREATE OR REPLACE PROCEDURE ogrBilgiGetir(
2
no IN DBUSER.ogrNo%TYPE,
3
ad OUT DBUSER.ogrAd%TYPE,
4
soyad OUT DBUSER.orgSoyad%TYPE)
5
IS
6
BEGIN
7
SELECT ogrAd, ogrSoyad
8
INTO ad, soyad
9
FROM ogrenci WHERE ogrNo = no;
10
END;
Yukarıdaki depolanmış yordam veritabanı üzerinde oluşturulur. Kısaca kayıtlı
yordamımız INparametresiyle dışarıdan bir parametre alır. OUT parametresiyle
dışarıya iki parametre gönderir. Sorgumuzda ise öğrenci no'sunu verdiğimiz
kişinin adını ve soyadını verecek bir SQL kodu yazdık. Şimdi bu kayıtlı
yordamın Java tarafından nasıl çağrıldığıyla ilgili örneğimize devam edelim.
1 //CallableStatementOrnek.java - 26.04.2014
2
3 import java.sql.CallableStatement;
4 import java.sql.Connection;
5 import java.sql.DriverManager;
6 import java.sql.ResultSet;
7 import java.sql.Statement;
8
9 public class CallableStatementOrnek
10 {
11
public static void main(String[] args)
12
{
13
try
14
{
15
Class.forName("com.mysql.jdbc.Driver");
16
// JDBC sürücüsünü yükledik
17
18
String bagMetni = "jdbc:mysql://localhost:3306/ogrenci";
19
Connection bag = DriverManager.getConnection(bagMetni, "root",
20 "12345");
21
// bağlantımızı oluşturduk
22
23
String sqlYordam = "{call ogrBilgiGetir(?, ?, ?)}";
24
CallableStatement callSt = bag.prepareCall(sqlYordam);
25
callSt.setInt(1, 3361);
26
// statement nesnemizi oluşturduk ve parametrelerimizi aktardık
27
callSt.registerOutParameter(2, java.sql.Types.VARCHAR);
28
callSt.registerOutParameter(3, java.sql.Types.VARCHAR);
29
callSt.executeQuery();
30
// veritabanından dönecek değerlerin tipini belirledik ve
31 yordamımızı çağırdık.
32
33
String ogrAd = callSt.getString(2);
34
String ogrSoyad = callSt.getString(3);
35
// veritabanından dönen değerleri string nesnemize aktardık
36
bag.close();
37
}
38
catch (Exception e)
39
{
40
e.printStackTrace();
41
}
42
}
}
RESULTSET
ResultSet, bileşenimiz, veritabanından dönen verileri içinde tutan bileşendir.
Verileri bir kere ResultSetbileşenimize yükledikten sonra bu
sınıfın next() metoduyla veri satırını elde edebiliriz. Daha sonra bu satır
üzerinde doğru tip metotlarına istenilen parametreleri vererek verileri elde
edebiliriz. Örneğin; elde ettiğimiz verinin ilk sütununda yer alan integer tipte
veriyi çekmek istiyorsak resultSetNesnesi.getInt(1) yöntemini kullanırız.
Şimdi bu bileşenin nasıl kullanıldığını görmek için bir örnek yapalım.
1 //ResultSetOrnek.java - 26.04.2014
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.ResultSet;
6 import java.sql.Statement;
7
8 public class ResultSetOrnek
9 {
10
public static void main(String[] args)
11
{
12
try
13
{
14
Class.forName("com.mysql.jdbc.Driver");
15
// JDBC sürücüsünü yükledik
16
17
String bagMetni = "jdbc:mysql://localhost:3306/ogrenci";
18
Connection bag = DriverManager.getConnection(bagMetni, "root",
19 "12345");
20
// bağlantımızı oluşturduk
21
22
Statement st = bag.createStatement();
23
// Statement nesnemizi oluşturduk
24
25
String sql = "SELECT * FROM ogrenci";
26
ResultSet sonuc = st.executeQuery(sql);
27
// SQL sorgumuzu çalıştırdık ve sonuç ResultSet nesnesine
28 yüklendi
29
30
while(sonuc.next())
31
{
32
System.out.println("Ogrenci ismi: " + sonuc.getString(1));
33
// kolon indisi ile veriyi aldık
34
35
System.out.println("Öğrenci ismi: " +
36 sonuc.getString("ogrSoyad"));
37
// kolon ismi ile veriyi aldık
38
}
39
bag.close();
40
}
41
catch (Exception e)
42
{
43
e.printStackTrace();
44
}
}
}
Yukarıdaki örneğimizde veritabanı bağlantımızı oluşturduk. SQL sorgumuzu
çalıştırdıktan sonra verilerimizResultSet bileşenimiz içerisine yüklendi.
Bundan sonraki kısımda elde ettiğimiz verileri while döngüsü venext() metodu
yardımıyla verilerin sonuna gelene kadar okuduk. Bu metot ile imleç her
seferinde bir alt satıra gelir. Verileri getString() metoduyla alırken ilk
bölümde verimizi kolon indisi yardımıyla elde ettik. İkinci bölümde ise yine
verimizi bu kez kolon ismi ile elde ettik.
Burada next() metodu ile imleci bir alt satıra kaydırdık her seferinde. Fakat
belirli bir satıra gitmesini istiyorsak, absolute() metodunun içerisine parametre
olarak satır sayısını veririz. Belirli bir sayı kadar alt satırlara inmesini istiyorsak
da relative() metoduna parametre olarak ilerlemek istediğimiz satır sayısını
veririz. İmlecimiz de bu metotlara göre hareket eder.
Ders 163 - JDBC İle Veri Sorgulama
JDBC ile işlem yaparken SQL sorgulama komutlarını kullanacağız. Dersimizde
yeri geldiği zaman ilgili SQL komutlarının da anlatımını göreceksiniz.
Veritabanında veri sorgulamayı SQL komutlarından SELECT komutu üstlenir.
Bu sorgu komutu istenilen tablodan istenilen alanları belirli kritere göre
çekmeye yarar. SELECTkomutunun genel kullanımı aşağıdaki gibidir.
1
SELECT ogrNo, ogrAd FROM ogrenci
Yukarıdaki sorgu komutu
örneğinde ogrenci tablosundan ogrNo ve ogrAd bölümlerini seçmek istedik.
Örnekteki gibi veritabanından belirli alanları çekmemiz
gerektiğinde SELECT sorgu komutunun yanına çekmek istediğiniz alanları,
aralarına virgül koyarak belirtebilirsiniz.
SELECT komutu ile verilerimi sorgularken bazen belirli şartlara göre veri
çekmemiz gerekebilir. Bu gibi durumlarda sorgu komutlarına şart komutu
eklememiz gerekir. Eğer şartımız belli bir değer ise WHERE;
değilse LIKE sorgu komutunu kullanırız. Bu komutların genel kullanımı
aşağıdaki gibidir:
1
SELECT ogrAd, ogrSoyad FROM WHERE ogrNo = 3361
2
SELECT ogrAd, ogrSoyad FROM LIKE ogrNo = '%36%'
Yukarıdaki ilk sorgu komutu öğrenci numarası 3361 olan
öğrencinin adını ve soyadını getirir. İkinci sorgu komutu ise, öğrenci numarası
içerisinde 36 olan öğrencinin adını ve soyadını getirir. Örnekte görüldüğü
gibiLIKE komutunun kullanımında % işaretleriyle öğrenci numarasının
bilmediğimiz yerlerini belirtiyoruz. Örnekte başını ve sonunu bilmediğimiz
içerisinde 36 geçen öğrenci numarası olan öğrencileri çektik. Tabi bu işareti
sadece başına koyarak öğrenci numarası 36 ile biten öğrencileri;
sonuna % işareti koyarak öğrenci numarası 36 ile başlayan öğrencileri elde
edebiliriz.
Şimdi bu sorgu komutlarının JDBC bileşenleri ile nasıl çalıştığını görmek için
bir örnek yapalım.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//veriSorgulama.java - 26.04.2014
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class veriSorgulama
{
public static void main(String[] args)
{
try
{
Class.forName("com.mysql.jdbc.Driver");
// JDBC sürücüsünü yükledik
String bagMetni = "jdbc:mysql://localhost:3306/test";
Connection bag = DriverManager.getConnection(bagMetni, "root",
"12345");
// bağlantımızı oluşturduk
Statement st = bag.createStatement();
Statement st1 = bag.createStatement();
// statement nesnemizi oluşturduk.
String sql = "SELECT ogrAd, ogrSoyad FROM Ogrenci LIKE
ogrNo = '3361'";
ResultSet sonuc = st.executeQuery(sql);
// ilk SQL sorgumuzu çalıştırdık ve sonuç ResultSet nesnesine
yüklendi
String sql1 = "SELECT ogrAd, ogrSoyad FROM Ogrenci LIKE
ogrNo = '%36%'";
ResultSet sonuc1 = st1.executeQuery(sql1);
// ikinci SQL sorgumuzu çalıştırdık ve sonuç ResultSet nesnesine
yüklendi
while(sonuc.next())
{
System.out.println("Öğrenci Adı: " + sonuc.getString("ogrAd"));
System.out.println("Öğrenci Soyadı: " +
sonuc.getString("ogrSoyad"));
}
// veritabanından gelen bilgileri yazdırdık
while(sonuc1.next())
47
{
48
System.out.println("Öğrenci Adı: " +
49 sonuc1.getString("ogrAd"));
50
System.out.println("Öğrenci Soyadı: " +
51 sonuc1.getString("ogrSoyad"));
52
}
53
// veritabanından gelen bilgileri yazdırdık
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Örneğimizde oluşturduğumuz SQL sorgularını daha öncede bahsettiğimiz
gibi Statement nesnemizinexecuteQuery() metoduna parametre olarak
gönderdik ve dönen sonucu ResultSet nesnemize aktardık. Veritabanından
dönen verilerin hepsini ekrana yazdırabilmek için while döngüsü
içerisine ResultSetnesnemizin next() metodunu yazdık. Bundan sonraki
kısımda ise verilerimizi ekrana yazdırmak
için ResultSetnesnemizin getString() metodunu kullandık. Bu metot içerisinde
de sütun isimlerini parametre olarak kullandık.
Ders 164 - JDBC İle Veritabanına Veri Ekleme
Veritabanına veri ekleyebilmek için SQL sorgu
komutlarından INSERT komutunu kullanacağız. Bu komuta önce
veritabanında hangi tabloya veri gireceğimizi belirtiriz. Veri gireceğimiz
tabloyu belirttikten sonra tablomuzun yanına tablo içerisindeki hangi
alanlara veri girişinin olacağını parantez içerisinde belirtiriz. En sonunda
belirtilen alanlar için verilerimizi VALUES etiketinin yanına parantez açarak
bu parantez içerisinde verilerimizi gireriz. Sorgu komutumuzu bu şekilde
yazdıktan sonra, Ders 162 - JDBC Bileşenleri dersinde anlattığımız
uygun statement metotlarından biri ile çalıştırırız. INSERT komutunun genel
yapısı aşağıdaki gibidir.
INSERT INTO ogrenci (ogrNo, ogrAd, ogrSoyad) VALUES (3361, 'Okan',
1
'Bilke')
Burada ogrNo, ogrAd, ogrSoyad alanlarına bilgi gireceğimizi
söyledik. VALUES kısmında ise eklenecek verileri sıraya göre yazdık.
INSERT sorgu komutunun JDBC ile nasıl kullanıldığıyla ilgili bir örnek
yaparak bu komutu daha iyi anlamaya çalışalım.
1 //veriEklemeOrnegi.java - 26.04.2014
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.ResultSet;
6 import java.sql.PreparedStatement;
7
8 public class veriEklemeOrnegi
9 {
10
public static void main(String[] args)
11
{
12
try
13
{
14
Class.forName("com.mysql.jdbc.Driver");
15
// JDBC sürücüsünü yükledik
16
17
String bagMetni = "jdbc:mysql://localhost:3306/test";
18
Connection bag = DriverManager.getConnection(bagMetni, "root",
19 "12345");
20
// bağlantımızı oluşturduk
21
22
String sql = "INSERT INTO ogrenci(ogrNo, ogrAd, ogrSoyad)
23 VALUES(?, ?, ?)";
24
PreparedStatement pSt = bag.prepareStatement(sql);
25
pSt.setInt(1, 3361);
26
// ilk ? kısmına 3361 ekledik
27
pSt.setString(2, "Okan");
28
pSt.setString(3, "Bilke");
29
/* PreparedStatement nesnemizi oluşturduk ve
30
* parametrelerimizi nesnemize geçirdik */
31
32
ResultSet sonuc = pSt.executeQuery();
33
// SQL sorgumuzu çalıştırdık ve sonuc ResultSet nesnesine
34 yüklendi
35
36
37
38
39
40
41
42
43
bag.close();
pSt.close();
// bağlantılar kapatıldı
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Yukarıdaki örneğimizde verileri ekleyebilmek için SQL sorgu ifademizi
oluşturduk ve bu ifademizi bağlantı nesnemizin prepareStatement() metoduna
parametre olarak gönderdik. PreparedStatement bileşenine bağlantı
nesnemizin bir örneğini aldıktan sonra, bu nesneye SQL sorgu ifademizde
kullanacağımız parametreleri göndermek için bu
nesnenin setInt() ile setString() metotlarını kullandık. Daha sonrasında bu
nesnemizin executeQuery() metodunu kullanarak sorgumuzu çalıştırdık ve
veritabanından dönen sonuçlarıResultSet nesnemize aktardık.
Ders 165 - JDBC İle Veritabanından Veri Silme
Veritabanındaki verileri silmek için SQL sorgu
komutlarından DELETE komutunu kullanacağız. DELETEkomutunun çok
basit bir yapısı vardır. DELETE sorgu komutu belirtilen tablodan belirtilen
kriterlere göre verileri siler. DELETE sorgu komutunun genel kullanımı şu
şekildedir:
DELETE FROM ogrenci WHERE ogrNo =
1
3361
Burada ogrenci tablosundan ogrNo verisi 3361 olan tüm kayıtları sildik.
Verileri silmek isterken şart komutunu kullanmazsak, sorgu komutu tablodaki
verilerin tamamını siler. Silme komutumuzun JDBC ile nasıl kullanıldığını
görmek için bir örnek yapalım.
//veriSilmeOrnegi.java - 26.04.2014
1
2
import java.sql.Connection;
3
import java.sql.DriverManager;
4
import java.sql.Statement;
5
6
public class veriSilmeOrnegi
7
{
8
public static void main(String[] args)
9
{
10
try
11
{
12
Class.forName("com.mysql.jdbc.Driver");
13
// JDBC sürücüsünü yükledik
14
15
String bagMetni = "jdbc:mysql://localhost:3306/test";
16
Connection bag = DriverManager.getConnection(bagMetni, "root",
17
"12345");
18
// bağlantımızı oluşturduk
19
20
Statement st = bag.createStatement();
21
// statement nesnemizi oluşturduk
22
23
String sql = "DELETE FROM ogrenci WHERE ogrNo = 3361";
24
st.executeQuery(sql);
25
// SQL sorgumuzu çalıştırdık.
26
}
27
catch (Exception e)
28
{
29
e.printStackTrace();
30
}
31
}
32
}
33
Yukarıdaki örneğimizde bağlantımızı oluşturduk ve Statement nesnemize
bağlantımızın adresini verdik. Daha sonrasında SQL sorgu ifademizi yazdık
ve Statement nesnemizin executeQuery() metoduyla yardımıyla komutumuzu
işleme koyduk. Bu örneğimizde ResultSet nesnesi kullanmadığımıza dikkat
edin.
DELETE komutunu kullandığımızda geriye veri dönmez.
Dolayısıyla ResultSet nesnesini kullanmaya gerek yoktur.
Ders 166 - JDBC İle Veritabanındaki Verileri Güncelleme
Veritabanındaki verileri güncellemek için UPDATE komutunu kullanırız.
Veritabanında güncelleyeceğimiz tablo adını UPDATE komutu yanına, alan
isimlerini ise SET komutunun yanına yazarak, alanlara yeni vereceğimiz
değerleri bu alanlara eşitleriz. Kriterimiz var ise verilerimiz yazdıktan sonra
kriterlerimizi WHEREveya LIKE komutu yardımıyla belirtiriz. Kriter
belirtmezsek, veritabanındaki tablodaki güncellenen alanların
tümü UPDATE komutuyla güncellenir. UPDATE komutunun genel kullanımı
şöyledir:
UPDATE ogrenci SET ogrAd = 'Okan', ogrSoyad = 'Bilke' WHERE ogrNo
1
= 3361
Burada ogrNo alanı 3361 olan
kaydın, ogrAd alanına Okan, ogrSoyad alanına Bilke yazıyoruz. Kullanmamız
gereken tablo ise ogrenci tablosudur. Bu tablo üzerinden işlem yaparız.
Şimdi güncelleme komutumuzun Java içerisinde nasıl kullanıldığını görmek
için bir örnek yapalım.
1 //veriGuncellemeOrnegi.java - 26.04.2014
2
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.Statement;
6
7 public class veriGuncellemeOrnegi
8 {
9
public static void main(String[] args)
10
{
11
try
12
{
13
Class.forName("com.mysql.jdbc.Driver");
14
// JDBC sürücüsünü yükledik
15
16
String bagMetni = "jdbc:mysql://localhost:3306/test";
17
Connection bag =
18 DriverManager.getConnection(bagMetni);
19
// bağlantımızı oluşturduk
20
21
Statement st = bag.createStatement();
22
// statement nesnemizi oluşturduk
23
String sql = "UPDATE ogrenci SET ogrAd = 'Okan',
24
ogrSoyad = 'Bilke' WHERE ogrNo =
25 3361";
26
// kullanacağımız sorgu cümlesi
27
28
st.executeQuery(sql);
29
// SQL sorgumuzu çalıştırdık
30
}
31
catch (Exception e)
32
{
33
e.printStackTrace();
34
}
}
}
Yukarıdaki örneğimizde bir önceki örnekte yaptığımız gibi SQL sorgumuzu
oluşturduk ve bunu Statementnesnemizin executeQuery() metoduna
parametre olarak verdik ve sorgumuzu çalıştırmış olduk.
Buraya kadar yaptığımız örneklerde bir veritabanımızın, tablomuzun ve
sütunlarımızın olduğunu varsaydık. Bir sonraki dersimizde veritabanımızı ve
tablolarımızı nasıl oluşturacağımızı öğreneceğiz.
Ders 167 - Navicat Kurulumu
Şimdiye kadar ki derslerimizde, tablomuzun ve sütunlarımızın olduğunu
varsaydık. Şimdi gerçekten veritabanımızı ve tablomuzu oluşturalım. Bunun
için Navicat programını kullanacağız. Bu program ile veritabanındaki tabloları
alanları görsel olarak oluşturacağız. Programımızda da bu veritabanına kayıtlar
ekleme, silme gibi işler yapacağız. İlk olarak Navicat programının kurulumunu
anlatalım.
İlk olarak Bu linke tıklayarak Navicat sitesine gidiyoruz. Karşımıza şöyle bir
ekran gelecektir.
Navicat for MySQL seçeneğinin altındaki Download Trial yazısına
tıklıyoruz, daha sonra aşağıdaki gibi bir ekran göreceğiz. Buradan işletim
sistemimize göre uygun olan sürümü indiriyoruz.
İndirip kurulum dosyamızı çalıştırdıktan sonra aşağıdaki adımları takip
ediyoruz.
Next ile ilerliyoruz.
Yükleme bittikten sonra artık programımızı kullanmaya başlayabiliriz.
Navicat, veritabanımızı görsel olarak yönetmemizi sağlar. Tablo oluşturabilir,
kullanıcı ekleyebilir, veritabanımıza sorgu ile eklenen kayıtları görebilir ve
daha birçok işlemleri yapabiliriz.
Bir sonraki dersimizde Navicat programımızı kullanarak temel veritabanı
işlemleri yapacağız.
Ders 168 - Navicat İle Örnek Uygulama
Şimdiye kadar yaptığımız ekleme, silme gibi işlemleri veritabanındaki tabloları
görsel olarak göstermedik. Sadece kod kısmında neler olduğunu anlattık. Şimdi
Navicat programı ile tablolar oluşturacağız. Veritabanı üzerinde yaptığımız
işlemlerin sonucunda nelerin değiştiğini görsel olarak veritabanımızda
göreceğiz.
Bunun için örnek olarak çalışanların bilgilerinin tutultuğu bir veritabanı
oluşturalım ve üzerinde temel işlemleri yapalım.
İlk olarak Navicat programımızı açıyoruz ve karşımıza şöyle bir arayüz geliyor.
Sol üstteki Connection butonuna tıklayıp MYSQL yeni bir bağlantı
oluşturuyoruz. Karşımıza gelen ekranı aşağıdaki gibi
dolduralım. Password alanına MySQL i kurarken girdiğimiz şifreyi
giriyoruz. Ders 160 - MySQL Kurulumu dersinde bunu anlatmıştık.
Doldurduktan sonra bağlantımız oluşturulacaktır. Daha sonra bağlantımıza sağ
tıklayalım ve New Database diyelim.
Daha sonra karşımıza gelen ekrandaki bilgileri aşağıdaki gibi dolduralım. UTF
- 8 olarak da işaretleyebilirsiniz.
Sol tarafta veritabanımızın eklendiğini göreceksiniz. Üzerine çift tıklayıp
altındaki dosyaları da açalım Daha sonra aşağıdaki gibi veritabanımızın üzerine
sağ tıklayalım ve New Table diyerek bir tablo ekleyelim.
Karşımıza aşağıdaki gibi bir ekran gelecektir. Buradaki gireceğimiz veriler,
tablomuzdaki sütunları oluşturuyor. Allow Null kısmını işaretlemedik. Çünkü
boş veri girilmesini istemiyoruz. Alt alta satırları oluşturmak için Add
Field butonuna basıyoruz. İlgili alanları doldurduktan sonra CTRL+S tuşlarına
basıyoruz ve bizden bir tablo adı girmemizi istiyor. Tablo adını da aşağıdaki
gibi gibi isci olarak giriyoruz.
Bu alanları doldurup kaydettikten sonra ekranı kapatıyoruz. Artık ana
ekranımızda tablomuz görünüyor. Bu tabloya sağ tıklayarak Open
Table diyoruz.
Burada karşımıza tablomuz gelecektir. İçi şuan boş. Biz buraya manuel olarak
birkaç bilgi girelim. Bilgileri girip CTRL+S tuşlarına basalım. Verileri
girdiğimiz ekran aşağıdadır. Verileri girerken yeni kayıt eklemek için ekranın
altındaki + tuşuna basabiliriz.
Veritabanımı, tablomuzu ve içindeki verileri oluşturduk. Şimdi Eclipse'de bir
proje açalım ve projemize yeni bir sınıf ekleyelim. Artık kod üzerinden bu
veritabanına ulaşacağız ve veritabanımızdaki değişiklikleri göreceğiz.
İlk olarak programımızı çalıştıracağımız isci sınıfını yazalım.
Bu isci sınıfının main metodu içerisinde gerekli işlemleri yapacağız.
Şimdi main metodunu boş bir şekilde verelim. Ekleme, çıkarma gibi sınıfları
oluşturunca bumain metodunu dolduracağız. Projemize başlamadan
önce MySQL Connector'ü Ders 161 - MySQL İçin JDBC Connector dersinde
anlattığımız şekilde projemize ekliyoruz.
isci Sınıfı:
1
//isci.java - 27.04.2014
2
3
public class isci
4
{
5
private String ad;
6
private String soyad;
7
private String sehir;
8
private String gorev;
9
10
public isci(String ad, String soyad, String sehir, String
11
gorev)
12
{
13
// yapıcı tanımlandı
14
this.ad = ad;
15
this.soyad = soyad;
16
this.sehir = sehir;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
this.gorev = gorev;
}
public String getAd() // setter ve getter metotlar yazıldı
{
return ad;
}
public String getSoyad()
{
return soyad;
}
public String getSehir()
{
return sehir;
}
public String getGorev()
{
return gorev;
}
public static void main(String[] args)
{
// main metodu şimdilik boş
}
}
Programımızı çalıştıracağımız isci sınıfını,
içerisindeki getter metotları, değişkenleri yazdık. Şimdi
projemize Ekleme adında bir sınıf oluşturalım. Daha sonra aşağıdaki kodları
yazalım. Bu sınıf, veritabanımıza kayıt ekleyecektir.
Ekleme Sınıfı:
1 //Ekleme.java - 27.04.2014
2
3 import java.sql.*;
4
5 public class Ekleme
6 {
7 public void ekle(isci i)
8
{
9
try
10
{
11
Class.forName("com.mysql.jdbc.Driver");
12
13Connection bag =
14DriverManager.getConnection("jdbc:mysql://localhost:3306/calisandb",
15"root", "12345");
16
// root ve 12345 alanına mysql kullanıcı adı ve şifrenizi girin.
17
18
String sql = "INSERT INTO isci VALUES(?, ?, ?, ?)";
19
PreparedStatement p1 = bag.prepareStatement(sql);
20
p1.setString(1, i.getAd()); // ? olan kısımlar dolduruluyor
21
p1.setString(2, i.getSoyad()); // ? olan kısımlar dolduruluyor
22
p1.setString(3, i.getSehir()); // ? olan kısımlar dolduruluyor
23
p1.setString(4, i.getGorev()); // ? olan kısımlar dolduruluyor
24
25
int sonuc = p1.executeUpdate();
26
if(sonuc == 1)
27
System.out.println("Kayıt Eklendi");
28
else
29
System.out.println("Kayıt eklenemedi");
30
p1.close();
31
bag.close();
32
// bağlantılar kapatıldı.
33
}
34
catch (Exception e)
35
{
36
e.printStackTrace();
37
}
38 }
}
Bu sınıftaki ekle() metodu, parametre olarak i nesnesi alıyor. Aldığı
bu i nesnesi üzerinden get()metotları ile ? olan kısımlara değerler
atıyor. executeUpdate() metodu, işlemden etkilenen satır sayısınıdöndürdüğü
için eğer ekleme işlemi sorunsuz yapıldıysa sonuc değişkeni 1 oluyor ve "Kayıt
Eklendi" yazıyor. Değilse "Kayıt Eklenemedi" yazısını konsolda gösteriyor.
Ekleme sınıfını oluşturduğumuza göre artık isci sınıfındaki main metodunun
içerisini doldurabiliriz. mainmetodumuzun içi aşağıdaki gibi olacaktır.
1 public static void main(String[] args)
2 {
3
isci i = new isci("elektro", "arge", "ankara", "database
4 administrator");
5
Ekleme e = new Ekleme();
6
e.ekle(i);
}
main metodumuza bu kodları yazdık. isci sınıfından bir nesne oluşturduk ve ilk
değerlerini verdik. Bu değerler, yapıcı sayesinde ilgili değişkenlere atandı.
Daha sonra Ekleme sınıfından nesne oluşturduk ve bu nesne
üzerinden Ekleme sınıfındaki ekle() metodunu çağırdık. Değer olarak
da i nesnesini gönderdik. Çünkü eklenecek kayıtların bilgileri bu i nesnesinde
tutuluyor. ekle() metoduna bakarsanız, isci sınıfından inesnesini parametre
olarak alıyor. Bu ekle() metodunda da getAd() gibi metotları çağırdık
ve isci sınıfında adbilgisini tutan getter metodu çağırmıştık.
Programımızı çalıştırdığımızda konsol ekranımızda aşağıdaki gibi bir çıktı elde
edeceğiz.
1
Kayıt Eklendi
Navicat programından da veritabanımızdaki eklenen kaydı görelim. Bunun
için isci adlı tabloya çift tıklayalım ve aşağıdaki eklenen kaydı görelim.
Programımızı çalıştırdığımızda eklenen kaydı yukarıda gördük.
Şimdi de silme işlemi yapan sınıfımızı yapalım.
Silme Sınıfı:
1 //Silme.java - 27.04.2014
2
3 import java.sql.*;
4
5 public class Silme
6 {
7 public void silme (String a)
8
{
9
try
10
{
11
Class.forName("com.mysql.jdbc.Driver");
12Connection bag =
13DriverManager.getConnection("jdbc:mysql://localhost:3306/calisandb",
14 "root", "12345");
15
// root ve password alanına kendi belirlediklerinizi girin
16
String sql = "DELETE from isci WHERE ad=?";
17
PreparedStatement p1 = bag.prepareStatement(sql);
18
p1.setString(1, a);
19
20
int sonuc = p1.executeUpdate();
21
if (sonuc ==1)
22
System.out.println("Kayıt Silindi");
23
else
24
System.out.println("Kayıt Silinemedi");
25
bag.close();
26
p1.close();
27
// bağlantılar kapatıldı
28
}
29
catch (Exception e)
30
{
31
e.printStackTrace();
32
}
33 }
34}
Bu sınıftaki silme() metodumuz ise bir String ifade alıyor. Yani
biz isci sınıfında silinmesini istediğimiz kişinin adını parametre olarak
göndereceğimiz için bunu yaptık. Sorgumuzda da ad değişkeni a'ya eşit olan
veriyi siliyor.
Şimdi yine isci sınıfının main metoduna ne yazacağımıza bakalım.
1
public static void main(String[] args)
2
{
3
Silme s = new Silme();
4
s.silme("Mustafa");
5
}
Silme sınıfından nesne oluştururuz ve bu nesne üzerinden silme() metodunu
çağırırız. Metoda parametre olarak da silinecek kişinin adını gireriz. İstersek
ada göre değil de başka bir veriye göre silme işlemi yapabiliriz. Bunun için
sorguda değişiklik yapmamız gerekir.
main metodumuzu çalıştırdığımızda konsol ekranındaki çıktımız şu şekilde
olacaktır:
1
Kayıt Silindi
Navicat programımızdan kayıtlara baktığımızda, adı Mustafa olan
veriyi sildiğini görürüz.
Görüldüğü gibi kaydımız silinmiştir.
Şimdi de Guncelleme adında bir sınıf oluşturalım ve daha sonra aşağıdaki
kodları yazalım.
Guncelleme Sınıfı:
1 //Guncelleme.java - 27.04.2014
2
3 import java.sql.*;
4
5 public class Guncelleme
6 {
7 public void Guncelleme(String soyad, String yeniGorev)
8
{
9
try
10
{
11
Class.forName("com.mysql.jdbc.Driver");
12
13Connection bag =
14DriverManager.getConnection("jdbc:mysql://localhost:3306/calisandb",
15"root", "12345");
16
// root ve 12345 alanına mysql kullanıcı adı ve şifrenizi girin.
17
18
String sql = "UPDATE isci SET gorev=? WHERE soyad=?";
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 }
}
PreparedStatement p1 = bag.prepareStatement(sql);
p1.setString(1, yeniGorev);
p1.setString(2, soyad);
int sonuc = p1.executeUpdate(); // sorgu çalıştırılır
if (sonuc == 1) // etkilenen satır varsa
System.out.println("Kayıt Güncellendi");
else
System.out.println("Kayıt Güncellenemedi");
bag.close();
p1.close();
// bağlantı kapatıldı
}
catch (Exception e)
{
e.printStackTrace();
}
Bu sınıftaki metodumuz soyad ve yeniGorev parametrelerini alıyor. Aldığı ilk
parametreyi sorgumuzdaki2. soru işaretinin olduğu yere ekliyor.
Diğer yeniGorev parametresini ise sorgudaki ilk soru işaretinin olduğu
yere ekliyor. Sorgumuz bu şekilde yapılandırılıyor. Bunu
ise prepareStatement ile sağlıyoruz.
Şimdi ise isci sınıfının main metoduna aşağıdaki kodları girelim.
1
public static void main(String[] args)
2
{
3
Guncelleme g = new Guncelleme();
4
g.Guncelleme("Tuna", "Patron");
5
}
isci sınıfını çalıştırdığımızda konsolda şu çıktıyı elde edeceğiz:
1
Kayıt Güncellendi
Navicat programımızdan kontrol ettiğimizde ise soyadı Tuna olan kişinin
görevini Patron yapıyor.
Listeleme Sınıfı:
1 //KayitGetir.java - 27.04.2014
2
3 import java.sql.*;
4
5 public class KayitGetir
6 {
7 public void KayitGetir(String ad)
8
{
9
try
10
{
11
Class.forName("com.mysql.jdbc.Driver");
12
13Connection bag =
14DriverManager.getConnection("jdbc:mysql://localhost:3306/calisandb",
15"root", "12345");
16
// root ve 12345 alanına mysql kullanıcı adı ve şifrenizi girin.
17
18
String sql = "SELECT * from isci WHERE ad=?";
19
PreparedStatement p1 = bag.prepareStatement(sql);
20
p1.setString(1, ad);
21
ResultSet sonuc = p1.executeQuery();
22
// sorgudan dönen değerler ResultSet'e aktarıldı
23
while(sonuc.next()) // ResultSet'teki tüm kayıtlar okundu
24
{
25
System.out.println(sonuc.getString("ad"));
26
System.out.println(" - ");
27
System.out.println(sonuc.getString("soyad"));
28
System.out.println(" - ");
29
System.out.println(sonuc.getString("sehir"));
30
System.out.println(" - ");
31
System.out.println(sonuc.getString("gorev"));
32
}
33
34
35
36
37
38
39
40 }
41}
bag.close();
p1.close();
}
catch (Exception e)
{
e.printStackTrace();
}
Yukarıdaki sınıfta metodumuz ad parametresi alıyor ve bu parametreyi
sorgumuza ekliyor. Sorgumuzda * from dediğimiz için WHERE şartına
uyan tüm kayıtları getirir. While döngüsünde ise şartımıza uyan tüm
kayıtları satır satır okuruz. Önceki örneklerdeki
gibi executeUpdate() metodunu çağırmadık çünkü etkilenen satır sayısı diye
bir şey yok. Sadece kayıtları getirme işlemi yapıyoruz. O
yüzden executeQuery() metodunu çağırdık.
isci sınıfının main metoduna ise aşağıdaki kodları
yazalım. KayitGetir sınıfından nesne oluşturarakKayitGetir adlı metoda
parametre olarak Okan String'ini gönderdik. İsmi Okan olan kayıtlar
getirilecek. Çünkü sorgumuzda WHERE ifadesinden sonra şart
olarak ad alanını koyduk.
public static void main(String[] args)
1
{
2
KayitGetir k = new KayitGetir(); // isci sınıfının main
3
metodu
4
k.KayitGetir("Okan");
5
}
Programı çalıştırdığımızda konsolda aşağıdaki gibi bir çıktı elde edeceğiz.
1
Okan - Bilke - Ankara - Yazılımcı
Adı Okan olan tüm kayıtları getirdi. Navicat üzerinden bir şeye bakmamıza
gerek yoktur. Çünkü biz sadece kayıt getirme işlemi yaptık.
Ders 169 - Thread Kavramına Giriş
Yazdığınız bir uygulamada bir metot işlenirken, aynı anda for döngüsünü
işleyemeyiz. Başka bir döngüye girmek için metodun işlenmesi gerekir. Fakat
gelişmiş uygulamalarda bu böyle olmayacaktır. Mesela; network üzerinde
iletişim sağlayan bir uygulama geliştirdiğimizde aynı anda veri alabilmeli ve
veri gönderebilmeliyiz.
Çalıştırdığınız her farklı blok için bir kanal açılır. Buna thread denir. Bu
sayede bir işin bitmesini beklemeden başka bir iş yapabiliriz.
Bilgisayar ortamında da bu böyledir. Aynı anda birçok programı açabilir ve
çalışmalarını sağlayabiliriz. Buna multithreading denir. Dediğimiz gibi açılan
her program için bir kanal verilir ve bu sayede programlarımızı eş
zamanlı olarak çalıştırabiliriz.
Thread kavramı için olaya başka yönden yaklaşalım. Yazacağımız büyük çaplı
uygulamalarımızda, işlemcimizi tek bir görev için uzun süre çalıştırmak, akılcı
bir çözüm olmayacaktır. Thread yapısı, uygulama işlemlerinin
işlemciyi zaman paylaşımlı olarak kullanmasını sağlar. Bu yüzden çok fazla
işlem yapacağımız veya işlemin icra edilmesi sırasında bekleme süresi olan
işlemlerimiz için thread yapısını kullanmak akılcı bir çözüm olacaktır. Başka
bir örnek vermek gerekirse; internetten veri indirirken, form üzerinde bazı
işlemlerinde yapılması gereken bir uygulama yapmamız gerekiyor. Bu durumda
normal şartlarda uygulamamız veri internetten indirilene kadar form üzerindeki
işlemleri gerçekleştiremeyecektir. Bu uygulama üzerinde threadyapısı
kullanılırsa, form üzerindeki işlemleri yapan metot ve internetten veri indirme
metodu zaman paylaşımlı olarak işlemciyi kullanır ve uygulama üzerinde
aksaklık olmaz.
Bundan sonraki dersimizde thread nasıl oluşturulur ve çalıştırılır onu göreceğiz.
Ders 170 - Thread Oluşturma
Java dilinde thread oluşturmanın iki yolu vardır. Bunlardan
birincisi thread sınıfını miras(extend) almaktır. Bu yöntemi kullandığınızda
başka sınıfları miras alamayacaksınız. İkinci yöntem ise Runnable arayüzünü
implement etmek. İkinci yöntem birinci yöntemden karmaşık yapısıyla daha
fazla kod yazmanızı gerektirebilir, ama başka sınıfları miras almanıza olanak
sağlayacaktır. Aşağıdaki örnekte thread sınıfını miras alarak nasıl thread
nesnesi oluşturulacağı gösterilmiştir.
//ThreadYapisi.java - 27.04.2014
1
2
public class ThreadYapisi
3
{
4
public static void main(String[] args)
5
{
6
Ornek o1 = new Ornek();
7
o1.start();
8
}
9
}
10
class Ornek extends Thread
11
{
12
public void run()
13
{
14
System.out.println("Ornek adlı kanal
15
çalışıyor");
16
}
17
}
18
Ekran çıktısı:
1
Ornek adlı kanal çalışıyor
Yukarıda, işlemlerimizi yapacağımız ornek adlı sınıfı, Thread sınıfından miras
alıyoruz. Bu sınıftan bir nesne oluşturuyoruz ve kanalı başlatmak
için start() metodunu kullanıyoruz. Bu metot çağırıldığında run()metodu
çalışır. Bu run() metodu, thread içerisinde yapılacak işlemleri içerir. Kısacası
bir sınıfın threadolabilmesi için run() metodunu içermesi
gerekir. Thread sınıfına ait bu run() metodu, override edilmiştir.
Başka bir örnek verelim.
1
//ThreadYapisi2.java - 27.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ThreadYapisi2
{
public static void main(String[]
args)
{
Ornek2 o1 = new Ornek2();
}
}
class Ornek2 extends Thread
{
public Ornek2()
{
start();
}
public void run()
{
for (int i = 0 ; i < 5 ; i++)
System.out.println(i);
}
}
Ekran çıktısı:
1
0
2
1
3
2
4
3
5
4
Bu örnekte ise nesnemiz üzerinden start() metodunu çağırmadık. Bir nesne
oluştuğu ilk anda çalışan yapıcı içerisine start() metodunu yazdık. Bu metot
da run() metodunu çağırdı ve for döngümüz çalıştı.
Thread sınfını miras alarak son bir örnek yapalım.
1
//ThreadYapisi3.java - 27.04.2014
2
3
public class ThreadYapisi3
4
{
5
public static void main(String[] args)
6
{
7
Ornek3 o1 = new Ornek3(3, "Okan");
8
}
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
}
class Ornek3 extends Thread
{
private int sayi;
private String ad;
public Ornek3(int sayi, String ad)
{
this.ad = ad;
this.sayi = sayi;
start();
}
public void run()
{
for (int i = 0 ; i < 5 ; i++)
System.out.println("Sayı ve Ad: " + ad + " - " +
sayi);
}
}
Ekran çıktısı:
1
Sayı ve Ad: Okan - 3
2
Sayı ve Ad: Okan - 3
3
Sayı ve Ad: Okan - 3
4
Sayı ve Ad: Okan - 3
5
Sayı ve Ad: Okan - 3
Bu örneğimizde de yapıcımız içinde atama işlemleri yaptık. Daha
sonra start() metodu ile kalanı başlattık. Başlatınca run() metodu çalıştı ve
içerisindeki işlemler yapıldı.
Runnable arayüzünü implement ettiğimizde is, Thread sınıfını miras
alamadığımız için bu sınıfa özel bazı metotları kullanamayacağız. Bu nedenden
dolayı ilk yönteme göre daha fazla kod yazmamız gerekecektir.
Aşağıdaki örnekte Runnable sınıfını implement ederek, nasıl thread nesnesi
oluşturulabileceği gösterilmiştir.
1
//threadOrnegiRunnable.java - 27.04.2014
2
3
public class threadOrnegiRunnable implements Runnable
4
{
5
Thread kanal;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// thread nesnemizi oluşturduk.
public void threadOrnegiRunnable()
{
kanal = new Thread(this);
// oluşturduğumuz nesneye metodumuzu referans olarak
verdik
kanal.start();
// nesnemizi başlattık
try
{
kanal.sleep(1000);
// nesnemizi beklettik
} catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void run()
{
threadOrnegiRunnable();
// yapılandırıcı metod
}
}
Yukarıdaki örneğimizde daha önceki yaptığımız örneğimizin aynısını, bu
sefer Runnable arayüzünüimplement ederek yaptık. Thread sınıfının
metotlarını kullanamadığımız için bu sınıfın metotlarına
oluşturduğumuz thread nesnesi üzerinden eriştik. Sınıfımızın metodunu yine
oluşturduğumuz nesneyereferans olarak gönderdik. Runnable arayüzünün
avantajı, daha önce de belirttiğimiz gibi başka sınıfları miras almaya olanak
sağlar.
Aşağıdaki örnek, thread nesnesi oluşturma ve kullanımı ile ilgilidir.
1
2
public class threadOrnek
3
{
4
public static void main(String[]
5
args)
6
{
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Thread thread = new
threadOrnk();
// thread nesnemizi oluşturduk
}
}
class threadOrnk extends Thread
{
threadOrnk()
{
start();
// thread başlatıldı.
}
public void run()
{
for (int i = 0 ; i <= 5 ; i++)
{
System.out.print(i);
}
// ekrana sayıları yazdırdık
}
}
Ekran çıktısı:
1
012345
Ders 171 - Thread'i Başlatmak ve Durdurmak
Thread nesnelerini belirli zamanlarda başlatıp durdurabiliriz. Bunun
için Thread sınıfının bize sağladığıstart() ve stop() metotlarını
kullanacağız. start() metodu ile Thread nesnemizin yaşam döngüsünü
başlatırız ve stop() metodu ile nesnemizin yaşam döngüsünü kalıcı olarak
sonlandırırız. Birden fazla Thread nesnesi çalışacaksa, ilk başlatılan nesnenin
daha önce çalışacağı garanti edilmez. Thread nesneleri işlemcinin çalışma
boşluklarına göre hareket ederler. Bu sebeple daha önce başlatılan nesnenin
önce çalışacağı garanti edilemez.
Aşağıdaki örnek Thread nesnelerini başlatıp durdurmayı gösteren ve
ekrana Thread numarasınıyazdıran bir örnektir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//threadBasDurOrnegi.java - 27.04.2014
public class threadBasDurOrnegi
{
public static void main(String[] args)
{
Thread thread1 = new threadOrnek("1.thread");
Thread thread2 = new threadOrnek("2.thread");
thread2.stop();
Thread thread3 = new threadOrnek("3.thread");
Thread thread4 = new threadOrnek("4.thread");
// nesnelerimiz oluşturduk ve 2. nesnemizi durdurduk.
}
}
class threadOrnek extends Thread
{
threadOrnek (String isim)
{
// nesnemize ismini verdik ve yapılandırdık
super (isim);
start();
// nesnemizi başlattık
}
public void run()
{
System.out.println(Thread.currentThread().getName());
// Şu an çalışır durumda olan nesnenin ismini ekrana
yazdırdık.
}
}
Ekran çıktısı:
1
3.thread
2
4.thread
3
1.thread
Örnekte görüldüğü gibi Thread sınıfını miras alan bir sınıf oluşturduk ve bu
sınıfımızdan nesne türettik. Birinci nesnemiz aynı zamanda ilk başlattığımız
nesnemiz oldu. Fakat ekran çıktımıza baktığımızda ise ilk
olaraküçüncü nesnemizin çalıştığını görüyoruz. İkinci nesnemiz de çalıştıktan
kısa bir süre sonra durdurduk. Bu kısa süre içerisinde ekran çktısında ikinci
nesnemizin çalıştığını da görebilirdik. Nesnemizi durdurduğumuz için ekran
çıktısında görmedik.
Thread nesneleri başlatılırken, dikkat edilecek bir diğer önemli nokta ise;
nesneyi iki kerebaşlatmamaktır. Thread nesnesini iki kere
başlatmamız IllegalThreadStateException hatasını üretmeye sebep olacaktır.
Bu noktayı daha iyi görebilmek için yukarıdaki örneğimizi değiştirelim.
//threadBasDurOrnegi2.java - 27.04.2014
1
2
public class threadBasDurOrnegi2
3
{
4
public static void main(String[] args)
5
{
6
Thread thread1 = new threadOrnek("1.thread");
7
thread1.start();
8
// nesnemizi oluşturduk ve 2. kez başlattık
9
}
10
}
11
12
class threadOrnek2 extends Thread
13
{
14
threadOrnek2 (String isim)
15
{
16
// nesnemize ismini verdik ve yapılandırdık
17
super (isim);
18
start();
19
// nesnemizi başlattık
20
}
21
22
public void run()
23
{
24
System.out.println(Thread.currentThread().getName());
25
// Şu an çalışır durumda olan nesnenin ismini ekrana
26
yazdırdık.
27
}
28
}
29
Ekran çıktısı:
1
Exception in thread "main" java.lang.IllegalThreadStateException
2
at java.lang.Thread.start(Unknown Source)
3
at threadBasDurOrnegi2.main(threadBasDurOrnegi2.java:8)
4
1.thread
Yukarıdaki örneğimizde görüldüğü gibi thread1 nesnemizi iki defa başlattık.
Ekran çıktımızda ise IllegalThreadStateException hatası verildiğini, ardından
ise nesnemizin icra edildiğini gördük.
Ders 172 - Thread'i Beklemeye Almak ve Devam Ettirmek
Thread nesnelerinin belirli aralıklarla çalışıp durmasını veya biz tekrar
çalışmasını isteyene kadar durmasını sağlayabiliriz. Nesnemizi üç yöntem ile
beklemeye alabiliriz.
1.
İlk yol, nesnemize bir süre vererek onu bu süre zarfı içerisinde
uykuya gönderme metodudur. Bu yöntemde nesnemize sleep() metodu
ile milisaniye cinsinden uyuması için bir süre göndeririz. Nesnemiz bu
süre zarfında uykuda bekler.
2.
İkinci yöntemde ise yield() metodunu kullanırız. Bu metot, kullanıldığı
nesne ile aynı önceliğe sahipThread nesnesinin çalışmasını bekler ve
bu nesnenin işi bittikten hemen sonra tekrar çalışır duruma geçer.
3.
Üçüncü yöntem ise nesne wait() metodu yardımıyla beklemeye alınır
ve tekrar çalışması için uyarılana kadar beklemede kalır. Nesneyi
tekrar çalışma durumuna geçirmek
için notify() veya notifyAll()metotlarını kullanırız.
Şimdi bu metotları daha iyi anlayabilmek için bir örnek yapalım.
1
//threadBekleme.java - 27.04.2014
2
3
public class threadBekleme
4
{
5
public static void main(String[] args) throws InterruptedException
6
{
7
for (int i = 1 ; i <= 3 ; i++)
8
{
9
Thread kanal1 = new threadOrnek(i, "thread1");
10
kanal1.yield();
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Thread kanal2 = new threadOrnek(i, "thread2");
// nesnelerimizi oluşturduk ve ilk nesnemizi kısa süreliğini
uyuttuk
}
}
}
class threadOrnek extends Thread
{
int sayi = 0;
String isim;
threadOrnek (int sayi, String isim) throws InterruptedException
{
super(isim);
this.sayi = sayi;
this.isim = isim;
start();
// nesnemizi başlattık
sleep(100);
// nesnemizi 0.1 sn uykuya aldık
}
public void run()
{
System.out.println(Thread.currentThread().getName() + "[" + sayi
+ "]");
// nesnemiz içerisindeki sayıyı yazdırdık
}
}
Ekran çıktısı:
1
thread1[1]
2
thread2[1]
3
thread1[2]
4
thread2[2]
5
thread1[3]
6
thread2[3]
Örneğimizde nesnelerimize verdiğimiz sayıları ekranda yazdırdık. Ekran
çıktısında görüldüğü gibi ilk nesnemizi, ikinci nesnemize kısa süreliğine
avantaj sağlamak için beklemeye aldık. sleep() metoduna verdiğimiz süre ile
nesnemizin 0.1 sn uyumasını sağladık. Uygulamamız bu işlem sayesinde
ekrana sonuçları0.1 sn aralıklarla yazdırdı.
Ders 173 - Bir Thread Nesnesine Öncelik Atamak
Kullanacağımız Thread nesnelerimizde bazı nesnelerimizin daha önce
çalışmasını veya daha öncelikli olmasını sağlayabiliriz. Öncelikli olan bu
nesnelere, işlemci daha çok yer ayırır ve öncelik tanır. Şimdi aşağıda bir örnek
yapalım ve öncelik konusunu örnek üzerinde gösterelim.
1 //threadYapisi.java - 27.04.2014
2
3 public class threadYapisi
4 {
5
public static void main(String[] args) throws
6 InterruptedException
7
{
8
thread1 t1 = new thread1();
9
t1.setPriority(Thread.MIN_PRIORITY); // öncelik
10 ataması
11
t1.start();
12
thread2 t2 = new thread2();
13
t2.setPriority(Thread.MAX_PRIORITY); // öncelik
14 ataması
15
t2.start();
16
}
17 }
18
19 class thread1 extends Thread
20 {
21
public void run()
22
{
23
while(true) // sonsuz döngü
24
{
25
System.out.println("Okan");
26
}
27
}
28 }
29
30 class thread2 extends Thread
31 {
32
public void run()
33
34
35
36
37
{
while(true) // sonsuz döngü
{
System.out.println("Onur");
}
}
}
Bu programın çıktısında, Onur isminin daha çok çıktığını göreceksiniz.
Çünkü t2 nesnesine yüksek öncelik atadık. Tam tersini yaptığımızda ise işlerin
farklı olduğunu göreceksiniz. Tabi işlemci, arkaplanda t2 kanalıdadaha çok
alan ayıracaktır.
Değerleri görebilmek için programı sonsuz
döngüye soktuk. Console'daki kırmızı renkli durdurma tuşuna basarak
programı durdurabilirsiniz.
Bu işlemi Thread sınıfının öncelik atama metodu olan setPriority() metodu ile
sağlarız. Bu metoda yineThread sınıfı içerisinde tanımlı olan üç sabitten birini
göndererek nesnemize öncelik atayabiliriz.
Bu sabitler şöyledir:

MIN_PRIORITY: Düşük öncelik.

NORM_PRIORITY: Normal öncelik, aynı
zamanda varsayılan öncelik tipidir.

MAX_PRIORITY: Yüksek öncelik.
Parentez içerisine yukarıdaki değerleri yazmak yerine sayısal değerler de
yazabiliriz.
Thread nesnesinin önceliğini yüksek atamak, düşük öncelikli nesnelere göre
erişimi kolaylaştıracaktır. BirThread nesnesine öncelik atayabileceğimiz gibi
nesnemizin önceliğini de kontrol edebiliriz. Bu işlemi isegetPriority(); metodu
ile halledebiliriz. Bu metot ile thread'lerin öncelikleri öğrenilir. Bu metotları
daha iyi görebileceğimiz bir örnek yapalım.
1
//threadOncelikOrnegi.java - 27.04.2014
2
3
public class threadOncelikOrnegi
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
public static void main(String[] args) throws
InterruptedException
{
Thread kanal1 = new threadOrnek("1. thread");
kanal1.setPriority(Thread.MIN_PRIORITY);
// ilk nesnemizi oluşturduk ve önceliği düşük olarak
atadık
Thread kanal2 = new threadOrnek("2. thread");
kanal2.setPriority(Thread.MAX_PRIORITY);
// ikinci nesnemizi oluşturduk ve önceliği yüksek olarak
atadık
Thread kanal3 = new threadOrnek("3. thread");
// üçüncü nesnemizi oluşturduk ve öncelik atamadık
System.out.println(kanal1.getPriority());
System.out.println(kanal2.getPriority());
System.out.println(kanal3.getPriority());
// nesnelerimizin öncelik değerlerini ekrana yazdırdık
}
}
class threadOrnek extends Thread
{
threadOrnek(String isim) // yapıcı
{
super(isim);
start();
// nesnemizi başlattık
}
public void run()
{
System.out.println(Thread.currentThread().getName());
// nesnemizin ismini yazdırdık
}
}
Ekran çıktısı:
1
1. thread
2
2. thread
3
4
5
6
1
10
5
3. thread
Yukarıdaki örneğimizde nesnelerimizi oluşturduktan sonra önceliklerini
belirledik. Daha sonrasında ise nesnelerimizin önceliklerini elde edebilmek için
sınıfımızın sağladığı metodu kullandık. Nesnelerimizin öncelikleri,
nesnelerimiz icra edilmeden elde edildi. Buna göre ilk nesnemizin önceliğinin
sayısal değeri en düşük, ikinci nesnemizin sayısal değeri en büyük ve öncelik
atamadığımız nesnemizin sayısal değeri ise bunlararasında kalıyor.
Nesnelerimize atadığımız öncelik değerlerine göre sayısal değerlerin öncelikle
doğru orantılı olduğunu söyleyebiliriz. Ekran çıktımızda tekrar baktığımızda ise
önceliği en yüksek olan nesnemizin ilk önce icra edildiğini ve önceliği en
düşük olan nesnemizin en son icra edildiğini görüyoruz.
Ders 174 - Thread'in Çalışıp Çalışmadığının Kontrolü
Thread nesneleriyle uygulama yazarken bazen nesnenin halen çalışıp
çalışmadığını kontrol etmemiz gerekir. Bazı durumlarda yapılacak işleri,
nesnenin çalışıp çalışmaması durumuna göre yönlendiririz. Bu gibi
durumlarda Thread sınıfının bize sağlamış olduğu isAlive() metodunu
kullanabiliriz. Bu metot, bize Threadnesnesi halen runnable durumunda
ise true, Thread nesnesi terminated (durdurulmuş) durumda ise,
geriyefalse değer döndürecektir. Şimdi bu metotla ilgili bir örnek yapalım.
1 //threadKontrolOrnegi.java - 27.04.2014
2
3 public class threadKontrolOrnegi
4 {
5
public static void main(String[] args) throws
6 InterruptedException
7
{
8
Thread kanal1 = new threadOrnek("1. thread");
9
Thread kanal2 = new threadOrnek("2. thread");
10
// nesnelerimizi oluşturduk
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
kanal1.stop();
// ilk nesnemizi durdurduk
System.out.println(kanal1.isAlive());
System.out.println(kanal2.isAlive());
// nesnelerimizin çalışıp çalışmadığının kontrolü
}
}
class threadOrnek extends Thread
{
threadOrnek(String isim)
{
super(isim);
start();
// nesnemizi başlattık
}
public void run()
{
System.out.println(Thread.currentThread().getName());
// nesnemizin ismini yazdırdık
}
}
Ekran çıktısı:
1
2. thread
2
false
3
false
Yukarıdaki örneğimizde öncelikle nesnelerimizi oluşturduk. Daha sonrasında
ilk nesnemizi durdurduk. Bundan sonra ise nesnelerimizin çalışıp çalışmadığını
ekrana yazdırdık.
Ders 175 - MultiThreading
MultiThreading, sözlük anlamıyla çok kanal anlamına gelmektedir. Çok
kanallı programlama sayesinde iki işlemi paralel olarak zaman
paylaşımlı yürütebiliriz. Thread'leri anlatırken işlemlerin thread'ler sayesinde
zaman paylaşımlı olarak işlemciyi kullandıkları fakat işlemcinin işlemleri çok
hızlı işlediğinden işlemlerin aynı anda yapıldığı izlenimine kapıldığımızı
anlatmıştık. Bazı durumlarda birçok işlem için birçok thread yapısı
kullanmamız gerekir. Bu thread yapıları
birbirinden bağımsız veya ortak işlemleri içerebilirler. Ortak işlemleri
işlediklerinde thread'lerin düzgün çalışabilmesi için thread'lerin
senkronizasyonunun sağlanması gerekmektedir.
Şimdi thread'lerin senkronizasyonu konusunu inceleyelim.
THREAD'LERİN SENKRONİZASYONUNU SAĞLAMAK
Thread nesneleriyle uygulama yazarken her zaman tek bir nesnenin
ilgileneceği veriler üzerinde çalışmayız. Bazı durumlarda Thread nesnelerinin
ortak veriler üzerinde işlem yapması gerekebilir. Böyle durumlarda veri
bütünlüğünün sağlanması için Thread senkronizasyonu kullanılır. Olabilecek
çakışmalar önlenir. Bu yöntem sayesinde bir Thread nesnesi, anahtar kelimeyle
işaretlenmiş yerdeki işini bitirene kadar başka Thread nesnesi bu alanda işlem
yapamaz. Thread senkronizasyonunu sağlamak için metodumuzu veya belirli
bir kod bloğunu synchronized anahtar kelimesiyle işaretleriz. Şimdi bu olay ile
ilgili bir örnek yapalım.
1
//threadSyncOrnegi.java - 27.04.2014
2
3
public class threadSyncOrnegi
4
{
5
public static void main(String[] args) throws
6
InterruptedException
7
{
8
Thread kanal1 = new threadOrnek(3, 6);
9
Thread kanal2 = new threadOrnek(2, 4);
10
// nesnelerimizi oluşturduk ve başlangıç değerlerini
11
verdik.
12
}
13
}
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class threadOrnek extends Thread
{
threadOrnek(int sayi, int sayi2)
{
// senkronize kod bloğu oluşturduk
synchronized (this)
{
start();
// nesnemizi başlattık
System.out.println();
for(int i = sayi ; i <= sayi2 ; i++)
{
System.out.print(i + " - ");
}
// ekrana sayıları yazdırdık
}
}
}
Ekran çıktısı:
1
3-4-5-62
2-3-4Yukarıdaki örneğimizde iki Thread nesnesi oluşturduk ve bu nesnelere değer
aralıkları verdik. Bu değer aralıklarını yapıcı metodumuz, sayıları ekrana
yazdırmak için kullandı. Buna göre ilk nesnemiz için metodumuz ekrana 36 arası sayıları; ikinci nesnemiz için 2-4 arası sayıları yazdıracaktı. Daha
önceki threadörneklerimizde de gördüğümüz gibi Thread nesnelerinde belli
bir sıra yoktu. Ekran çıktımıza baktığımızda ise ilk ve ikinci nesnemizin sırayla
çalışmış olduğunu görüyoruz. Bunun sebebi; oluşturduğumuz senkronize kod
bloğudur. İlk nesnemiz bu kod bloğu içerisine ilk olarak girer. Bu nesnemizin
işi bitene kadar diğer Threadnesneleri bu bloğun içerisine giremezler.
Bu örneğimizde senkronizasyonu, bir kod bloğu oluşturarak sağladık.
Senkronizasyonu sağlamanın bir diğer yolu da oluşturacağımız
metodu synchronized anahtar kelimesiyle işaretlemektir. Buna göre yukarıdaki
örneğimizi bu yönteme göre düzenlersek:
1 //threadSyncOrnegi.java - 27.04.2014
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class threadSyncOrnegi2
{
public static void main(String[] args) throws
InterruptedException
{
Thread kanal1 = new threadOrnek2(3, 6);
Thread kanal2 = new threadOrnek2(2, 4);
// nesnelerimizi oluşturduk ve başlangıç değerlerini
verdik.
}
}
class threadOrnek2 extends Thread
{
int sayi, sayi2;
private synchronized void threadSync()
{
System.out.println();
for(int i = sayi ; i <= sayi2 ; i++)
{
System.out.print(i + "-");
}
// ekrana sayıları yazdırdık
}
threadOrnek2(int sayi, int sayi2)
{
start();
// nesnemizi başlattık
this.sayi = sayi;
this.sayi2 = sayi2;
}
public void run()
{
threadSync();
}
}
Ekran çıktısı:
1
2-3-3-4-5-6-4-
Bu yazım şekli ile bir önceki yazım şekli ile aynıdır. Aralarında uygulamasal
olarak bir fark yoktur.
Ders 176 - Switch İçerisinde String İfadeleri Kıyaslama
Kontrol Yapıları ve Döngüler derslerinde switch yapılarını anlatırken bundan
bahsetmiştik. switch ile kontrol yaparken
yalnızca Primitive tipleri switch içerisine ekleyebiliyorduk. Java 7 ile gelen
özellikle artıkswitch içerisinde String ifadeleri de karşılaştırabiliyoruz.
Örnek vererek açıklayalım.
1 //SwitchYapisi.java - 27.04.2014
2
3 import java.util.Scanner;
4
5 public class SwitchYapisi
6 {
7
public static void main(String[] args) throws
8 InterruptedException
9
{
10
Scanner s = new Scanner(System.in);
11
for (int i = 0 ; i < 3 ; i++)
12
{
13
System.out.println("İsminizi Girin: ");
14
String ad = s.next();
15
switch (ad)
16
{
17
case "Okan":
18
case "okan":
19
System.out.println("Adınız Okan'dır");
20
break;
21
case "Onur":
22
case "onur":
23
System.out.println("Adınız Onur'dur");
24
break;
25
default:
26
System.out.println("Adınız hiçbirisi değil");
27
}
28
}
29
}
30 }
31
Ekran çıktısı:
1
İsminizi Girin:
2
Okan
3
Adınız Okan'dır
4
İsminizi Girin:
5
onur
6
Adınız Onur'dur
7
İsminizi Girin:
8
göksu
9
Adınız hiçbirisi değil
Örneğimizde döngü ile kullanıcıdan 3 defa isim girmesini istedik. Girilen
bu String değerlerini switchyapısı ile karşılaştırdık. Girilen isme göre ekrana
bilgilendirme mesajı yazdık. Java 6'da bu özellik yoktu.
Yalnızca Primitive tipleri switch içerisinde kullanabiliyorduk.
Bu gelen yenilikten önce karşılaştırmamızı şu şekilde yapıyorduk.
1
//SwitchYapisi2.java - 27.04.2014
2
3
import java.util.Scanner;
4
5
public class SwitchYapisi2
6
{
7
public static void main(String[] args) throws
8
InterruptedException
9
{
10
Scanner s = new Scanner(System.in);
11
for (int i = 0 ; i < 3 ; i++)
12
{
13
System.out.println("İsminizi Girin: ");
14
String ad = s.next();
15
16
if(ad.equals("Okan"))
17
System.out.println("Adınız Okan'dır");
18
else if(ad.equals("Onur"))
19
System.out.println("Adınız Onur'dur");
20
else
21
System.out.println("Adınız hiçbirisi değil");
22
}
23
}
24
}
25
Ders 177 - Sayılarda Altçizgi Kullanarak Sayıları Bölümleme
Java7 ile gelen bir özellik ile int, float gibi sayısal veri tiplerimiz
içerisinde altçizgi (_) kullanabiliyoruz. Bunu farklı amaçlar için yapabiliriz.
Mesela; bir telefon numarasını ayırt etmek için kullanabiliriz. Örnek üzerinde
gösterelim.
//Java7.java - 27.04.2014
1
2
public class Java7
3
{
4
public static void main(String[] args) throws
5
InterruptedException
6
{
7
int tel = 444_67_444;
8
System.out.println(tel);
9
int ogrNo = 10_90_406_22;
10
System.out.println(ogrNo);
11
int sonuc = 56_4 + 12_8;
12
System.out.println(sonuc);
13
float sayi = 47_6;
14
System.out.println(sayi);
15
}
16
}
17
18
Ekran çıktısı:
1
44467444
2
109040622
3
692
4
476.0
Değişkenlerin değerlerine, okunabilirliği arttırmak için _ koyabiliyoruz. Tabi
bu çizgiler, derleyici tarafındanokunmuyor. Örneğimizde toplama işlemi
yaptık fakat altçizgi yokmuş gibi davrandı. Genelde telefon numarası gibi hane
ve bölümlere ayırmak için kullanılır. Bu da Java 7 ile gelen hoş bir özelliktir.
!
Istisnalar:
Altçizgi, sayılarımızın başına ve sonuna
gelemez. Böyle kullanılırsa derleyici hata üretir.
Yalnızca sayılarımızın aralarına koyulabilir.
Ders 178 - İkili Tabandaki Sayıları Değişkenlerde Tutma
Java 7'den önce değişkenlerimizde sadece o tipteki verileri tutabiliyorduk.
Örneğin; int tipindeki bir değişkende int tipindeki bir değeri, float tipindeki
değişkenlerde float tipindeki bir değeri tutmamız gibi. Java 7 ile gelen yenilikle
artık değişkenlerimizde binary sayıları da tutabiliyoruz.
Örnek verirsek:
//Java7.java - 27.04.2014
1
2
import java.util.Scanner;
3
4
public class Java7
5
{
6
public static void main(String[] args) throws
7
InterruptedException
8
{
9
int x = 0b11110;
10
float y = 0b01010;
11
byte z = 0b111111;
12
System.out.println(x);
13
System.out.println(y);
14
System.out.println(z);
15
}
16
}
17
18
Ekran çıktısı:
1
30
2
10.0
3
63
Örneğimizde değişkenlerimiz içerisinde binary tipteki sayıları da tutabiliyoruz.
Bunun için binary sayımızın başına 0b (sıfır-b) getiriyoruz.
Böylece binary sayımız, onluk tabana dönüştürülerek değişkenlerimizde
tutulabiliyor. Java 7'den önce bu şekilde tanımlama yapamıyorduk.
Peki, Java 7'den önce nasıl tanımlama yapıyorduk, onu inceleyelim. Binary
sayımızın tanına vereceğimiz parametre ile hangi tabanda dönüştürme
yapacağımızı söylüyoruz. Fakat Java 7 ile gelen yenilikle beraber artık bunu
kısa yoldan yapıyoruz.
//Ornek.java - 27.04.2014
1
2
public class Ornek
3
{
4
public static void main(String[] args) throws
5
InterruptedException
6
{
7
int a = Integer.parseInt("001100", 2);
8
System.out.println(a);
9
int b = Integer.parseInt("111", 8);
10
System.out.println(b);
11
int c = Integer.parseInt("1111", 10);
12
System.out.println(c);
13
int d = Integer.parseInt("10101010", 16);
14
System.out.println(d);
15
}
16
}
17
18
Ekran çıktısı:
1
12
2
73
3
1111
4
269488144
Yukarıda 4 adet binary sayı tanımladık. Bunları çift tırnak içerisinde
yazıyoruz. Daha sonra yanına, hangi tabana dönüştürme yapacağımızı
yazıyoruz. Bu işlemleri Integer.parseInt() metodu ile yapıyoruz. Bunun
yerine Integer.valueOf() metodu ile de yapabilirdik. 3. satırda onluk tabanda
yazılmasını istedik. Bu da doğrudan sayının kendisi oldu. Onluk taban sayının
kendisi oluyor her zaman. Son satırda ise 16'lık tabanda 10101010 sayısını
yazdırmak istedik ve sonuçları inceledik.
Bu işlemleri Java 7 ile tek satırda yapabiliyoruz. Doğrudan binary sayımızın
başına 0b getirerek sayımızı bir değişkene atayabiliyoruz.
Son bir örnek olarak Java 7 ile gelen özelliği kullanarak bir dizi oluşturalım ve
dizi elemanlarını ekrana yazdıralım.
//JavaSE7.java - 27.04.2014
1
2
public class JavaSE7
3
{
4
public static void main(String[] args) throws
5
InterruptedException
6
{
7
int[] dizi = {0b1100, 0b01110, 0b100110};
8
for (int i = 0 ; i < dizi.length ; i++)
9
{
10
System.out.println(dizi[i]);
11
}
12
}
13
}
14
15
Ekran çıktısı:
1
12
2
14
3
38
Dizimizin içerisinde binary elemanlar, otomatik olarak int tipine
dönüştürülerek saklanmıştır.
Ders 179 - Hata Yakalamada Yeni Catch Bloğu Sistemi
Exception dersinde anlatmıştık; programımızda bir hata
yakalandığında catch bloğu içerisinde kodlar işleniyordu. Eğer birden
fazla hata olma ihtimali varsa, biz de o kadar catch bloğu oluşturuyorduk.
Java 7 ile gelen yenilikle birden fazla catch bloğu oluşturmak yerine tek catch
bloğu içerisinde bunları kontrol edebiliyoruz.
Bir örnekle açıklayalım.
1
2 public class Java7
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
public static void main(String[] args) throws
InterruptedException
{
try
{
int x = 10;
int y = 0;
System.out.println(x / y);
}
catch (ArrayIndexOutOfBoundsException |
ArithmeticException ex)
{
System.out.println(ex.toString());
}
}
}
Ekran çıktısı:
1
java.lang.ArithmeticException: / by zero
Yukarıdaki örnekte catch bloğu içerisinde, doğabilecek tüm hata tiplerini
araya bitwise (|) koyarak tanımladık. Bu hata tiplerinden herhangi
biri try içerisinde olursa, catch içerisindeki kodlar işlenecektir. Java 7'den
önceki sürümlerde bunları tek tek kontrol ediyorduk. Aynı örneği bir de Java
7'den önce nasıl yaptığımıza bakalım.
1 //Java6.java - 27.04.2014
2
3 public class Java6
4 {
5
public static void main(String[] args) throws
6 InterruptedException
7
{
8
try
9
{
10
int x = 10;
11
int y = 0;
12
System.out.println(x / y);
13
}
14
catch (ArrayIndexOutOfBoundsException ex)
15
16
17
18
19
20
21
22
{
System.out.println(ex.toString());
}
catch (ArithmeticException ex)
{
System.out.println(ex.toString());
}
}
}
Ders 180 - Hata Yakalamada Finally Bloğunun Alternatifi
Hata yakalama işlemi yaparken genelde dosyalama ve veritabanı işlemlerinde
kapatılması gereken dosyaları ve bağlantıları finally bloğu içerisinde
kapatıyorduk. Java 7 ile gelen yenilikle beraber, artık tryiçerisinde de bunları
yapabileceğiz.
try bloğunu tanımlarken parantez içerisinde kapanmasını istediğimiz dosya ve
bağlantıları tanımlıyoruz ve bunlar otomatik olarak kapatılıyor.
Şimdi bir örnek verelim.
1 //FileReaderSinifiOrnek.java - 27.04.2014
2
3 import java.io.*;
4
5 public class FileReaderSinifiOrnek
6 {
7
public static void main(String[] args) throws
8 InterruptedException
9
{
10
File f = new File("C:\\elektroarge\\sehirler.txt");
11
File ff = new File("C:\\elektroarge\\sehirler2.txt");
12
char veriler[] = new char[(int) f.length()];
13
14
try(FileWriter yazdir = new FileWriter(ff))
15
{
16
FileReader f2 = new FileReader(f);
17
f2.read(veriler);
18
String okunan = new String(veriler);
19
yazdir.write(okunan);
20
}
21
catch (IOException e)
22
{
23
e.printStackTrace();
24
}
25
}
26 }
27
Örneğimizde try ifadesinin yanına parantez içerisinde kapatılacak olan
dosyamızı yazıyoruz. Bu, oluşturulan herhangi bir bağlantı nesnesi de
olabilirdi. Java 7'den önceki sürümlerde ise bu şekilde yapamıyor, kapatılacak
olan dosyaları finally bloğu içerisinde yazıyorduk. Artık bu bizim
için otomatik olarak yapılıyor. Bunun sebebi, Java 7'de, java.lang paketinin
içerisine AutoClosable arayüzünün eklenmiş olmasıdır.
Peki, bu örneğimizi JavaSE 7'den önce nasıl yapıyorduk, onu gösterelim.
1
//FileReaderSinifiOrnek2.java - 27.04.2014
2
3
import java.io.*;
4
5
public class FileReaderSinifiOrnek2
6
{
7
public static void main(String[] args) throws
8
InterruptedException
9
{
10
File f = new File("C:\\elektroarge\\sehirler.txt");
11
File ff = new File("C:\\elektroarge\\sehirler2.txt");
12
char veriler[] = new char[(int) f.length()];
13
14
try(FileWriter yazdir = new FileWriter(ff))
15
{
16
FileReader f2 = new FileReader(f);
17
f2.read(veriler);
18
String okunan = new String(veriler);
19
yazdir.write(okunan);
20
}
21
catch (IOException e)
22
{
23
e.printStackTrace();
24
}
25
finally
26
{
27
yazdir.close();
28
}
29
}
30
31
}
Ders 181 - Elmas Operatör İçerisindeki Tanım Zorunluluğu
Generic tipleri tanımlamak için kullandığımız < > operatörüne elmas
operatör diyoruz. Eskiden Java'da bir generic nesnesinin tanımını yaparken
hem nesne tanımında hem de nesneyi oluştururken (instance alırken) elmas
operatör ile tür belirtmek zorundaydık. Bu durum bazen nesne tanımı yaparken
büyük karmaşalara sebep olabiliyordu. Java 7'de ise sadece nesne tanımını
yaparken, generic nesnenin tipinin belirlemek yeterli olacaktır.
Bir örnek içerisinde bu durumun Java 7'den önce ve sonra nasıl olduğunu
gösterelim.
//listOrnegi.java - 27.04.2014
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.ArrayList;
import java.util.Map;
public class listOrnegi
{
Map<Integer, ArrayList<String>> Java7denOnce = new
Map<Integer, ArrayList<String>>();
// Java 7 den önce new Map <tip belirtmek zorunlu> ();
Map<Integer, ArrayList<String>> Java7denSonra = new
Map<>();
// Java 7 den sonra instance alırken tip belirtimi zorunluluğu
kalktı
}
Ders 182 - Safevarags İle Uyarı ve Hata Giderimi
Java'nın eski versiyonlarında varags() metodunu, parametre sayısı belli
olmayan bir değişkenle çağırdığınızda, derleyici bu bölüm için uyarı mesajı
vermekteydi.
Şu örnek üzerinden konumuza devam edelim.
//varags.java - 27.04.2014
1
2
import java.util.Map;
3
import java.util.HashMap;
4
5
public class varags
6
{
7
// çok parametreli(Varargs) metod
8
public static <Tip> void yazdir(Tip...elemanlar)
9
{
10
for(Tip t : elemanlar)
11
{
12
System.out.println(t.toString());
13
}
14
}
15
16
public static void main(String[] args)
17
{
18
yazdir("Merhaba", "-", "JAVA SE", "-", "7");
19
// bu kısımda derleyici hata veya uyarı vermeyecektir
20
21
Map<Integer, String> map1 = new HashMap<>();
22
Map<Integer, String> map2 = new HashMap<>();
23
// map türünden nesnelerimizi tanımladık.
24
25
map1.put(1, "Bir");
26
map1.put(2, "İki");
27
map2.put(3, "Üç");
28
map2.put(4, "Dört");
29
// map nesnelerimize değerleri ekledik
30
31
yazdir(map1, map2);
32
/* bu kısımda derleyici bize bir uyarı mesajı verecektir. bu
33
uyarı:
34
* WARNING: Type safety: A generic array of Map<Integer,
35
String>
36
* is created for a varags parameter şeklinde olacaktır
*/
37
}
38
}
39
Ekran çıktısı:
1
Merhaba
2
3
JAVA SE
4
5
7
6
{1=Bir, 2=İki}
7
{3=Üç, 4=Dört}
Örnekte derleyici, yazdir() metodunun ikinci kullanımında bu metodun bir
dizisini oluşturmaya çalışıyor. Derleme anında bu parametrelerin tipleri
silinerek derleniyor. Bu da tip uyuşmazlığı gibi sorunlara neden oluyor.
Örnekteki uyarı, bu hatanın alınabileceğini belirtmek için çıkıyor. Bu gibi
uyarıları almamamız için metodun başına @SafeVarargs annotation tipini
kullanabiliriz. Bu annotation'u kullanmak, alacağımız uyarıları bastıracaktır.
Yani bu annotation'u kullandığımızda örneğimiz aşağıdaki gibi olacaktır ve
uyarı mesajı bastırılacaktır.
1
//varags2.java - 27.04.2014
2
3
import java.util.Map;
4
import java.util.HashMap;
5
6
public class varags2
7
{
8
@SafeVarargs
9
// çok parametreli(Varargs) metod
10
public static <Tip> void yazdir(Tip...elemanlar)
11
{
12
for(Tip t : elemanlar)
13
{
14
System.out.println(t.toString());
15
}
16
}
17
18
public static void main(String[] args)
19
{
20
yazdir("Merhaba", "-", "JAVA SE", "-", "7");
21
// bu kısımda derleyici hata veya uyarı
22
vermeyecektir
23
24
25
26
27
28
29
30
31
32
33
34
35
Map<Integer, String> map1 = new
HashMap<>();
Map<Integer, String> map2 = new
HashMap<>();
// map türünden nesnelerimizi tanımladık.
map1.put(1, "Bir");
map1.put(2, "İki");
map2.put(3, "Üç");
map2.put(4, "Dört");
// map nesnelerimize değerleri ekledik
yazdir(map1, map2);
// uyarı mesajı almıyoruz
}
}

Benzer belgeler

java programlamaya giriş

java programlamaya giriş Burada kırmızı çizgilerle belirtilmiş olan programlar kurulmalıdır. Önce JDK daha sonra NetBeans IDE kurulur.

Detaylı