BukuOOP Seno
BukuOOP Seno
MEMAHAMI PEMROGRAMAN
Seno Adi Putra
BERORIENTASI OBYEK
DENGAN
JAVA
Edisi Pertama
Penulis :
Seno Adi Putra, S.Si, MT
Pembina Laboratorium Pemrograman
Program Studi Sistem Informasi
Fakultas Rekayasa Industri
Institut Teknologi Telkom
Penanggung Jawab :
Avon Budiyono, ST, MT
Kepala Program Studi Sistem Informasi
Fakultas Rekayasa Industri
Institut Teknologi Telkom
Didukung oleh :
Program Studi Sistem Informasi
Fakultas Rekayasa Industri
Institut Teknologi Telkom
KATA PENGANTAR
Seno Adi Putra
Puji dan syukur penulis panjatkan kehadirat Allah swt karena atas berkat rahmat dan karunia-Nya
penulis dapat menyelsaikan buku berjudul Memahami Pemrograman Berorientasi Obyek dengan Java
ini dengan selamat.
Teknologi Java merupakan salah satu teknologi yang saat ini berkembang pesat dalam waktu yang
sangat singkat. Penerimaan Java yang meluas ini mencerminkan kekuatan dan fitur teknis Java yang
handal. Karakteristik Java meliputi : platform yang netral, dinamis, Berorientasi obyek, penghapusan
obyek secara otomatis, keamanan yang tinggi, dan handal. Bahasa Pemrograman Java telah menjadi
bahasa pemrograman yang memiliki banyak kegunaannya. Java library mendukung pengembangan
aplikasi dalam berbagai platform.
Teknologi Java menawarkan solusi dalam berbagai platform mulai dari platform untuk aplikasi desktop
(Java Standard Edition, J2SE), platform aplikasi enterprise (Java Enterprise Edition, J2EE), hingga
aplikasi mobile (Java Micro Edition, J2ME).
Para pengembang piranti lunak telah mengadopsi Java bukan sekedar untuk suatu pekerjaan
pengembangan aplikasi, tapi juga cukup menyenangkan dan praktis. Java menghilangkan sesuatu yang
membosankan dan meminimalisir kesalahan terus menerus pada pengembangan aplikasi. Java
memberikan para pengembang untuk memusatkan seluruh energinya pada rancangan dan funsionalitas
program.
Prinsip Java adalah "Keep it simple! dan "Keep it learnable!", dalam arti bahwa Java merupakan bahasa
yang mudah dipelajari karena kesederhanaannya. Oleh karena itu, saat ini telah banyak yang
menggunakan Java mulai dari kalangan pelajar, programmer, pengembang, dan praktisi IT dalam
pembangunan perangkat lunaknya.
Buku ini tidak membahas semua platform Java, namun hanya membahas Java Standard Edition saja.
Buku ini membahas utuh pemrograman Java Standard Edition mulai dari fundamental Java
Programming Language, Java Programming, dan Java Workshop untuk membangun aplikasi berbasis
Java Standard Edition.
Selain membahas tentang pemrograman berorientasi obyek menggunakan Teknologi Java, buku ini juga
menyediakan soal-soal praktikum dan soal-soal ujian sertifikasi internasional sehingga diharapkan buku
ini dapat dijadikan rujukan yang dapat membantu pembacanya untuk menguasai pemrograman Java
sekaligus mengambil sertifikasi internasional Java.
Penulis sadari bahwa buku ini masih jauh dari sempurna. Untuk itu segala saran dan kritik yang
membangun dalam perbaikan buku ini untuk edisi selanjutnya dan penyusunan buku lainnya sangat
penulis harapkan. Namun demikian, mudah-mudahan buku ini bermanfaat bagi semua pihak.
DAFTAR ISI
Seno Adi Putra
KATA PENGANTAR
DAFTAR ISI
ii
PROFIL PENULIS
vii
13
1.1 Pendahuluan
1.2 Pemrograman
1.2.1 Bahasa Pemrograman
1.2.2 Level Bahasa Pemrograman
1.2.3 Bahasa Pemrograman Java
1.3 Siklus Hidup Piranti lunak
1.3.1 Analisis
1.3.2 Disain
1.3.3 Pengembangan (Development)
1.3.4 Pengujian (Testing)
1.3.5 Implementasi ( Implementation )
1.3.6 Pemeliharaan (Maintenance)
1.3.7 Akhir Siklus ( End-Of-Life )
13
13
13
14
14
15
15
16
16
16
17
18
18
19
2.1
2.2
2.3
2.4
2.5
2.6
Pendahuluan
Contoh Masalah
Identifikasi Domain Masalah
Identifikasi Obyek
Seleksi Obyek
Solusi
19
19
19
20
21
22
23
23
25
31
33
33
36
39
41
41
42
48
49
55
56
56
58
59
ii
61
63
63
63
65
61
61
62
65
66
66
66
68
71
73
73
75
78
78
79
80
81
81
85
85
86
87
88
88
89
89
91
92
95
95
96
97
97
98
98
99
101
BAB 13 ARRAY
13.1
13.2
13.3
13.4
13.5
13.6
103
103
103
105
107
107
108
111
114
115
115
116
116
117
119
120
120
121
121
122
123
124
124
125
126
126
131
Mendeklarasikan Array
Membuat Array
Menginisialisasi Array
Array Multidimensi
Batasan Array
Manipulasi Array
103
131
131
133
133
134
134
135
135
136
136
137
137
138
139
139
140
141
141
141
141
142
ii
143
145
145
145
iv
146
147
149
151
152
153
156
159
159
159
160
163
168
169
171
175
177
179
181
182
182
183
184
184
184
185
186
191
191
193
195
196
199
200
203
204
204
206
207
208
210
213
216
217
219
220
222
222
223
226
227
18.1
18.2
18.3
18.4
18.5
18.6
LAMPIRAN A
LAMPIRAN B
LAMPIRAN C
LAMPIRAN D
LAMPIRAN E
LAMPIRAN F
LAMPIRAN G
LAMPIRAN H
LAMPIRAN I
LAMPIRAN J
Menggunakan Connection
Menggunakan Statement
Menggunakan ResultSet
Proses Batch
Transaksi
Studi Kasus
PRAKTIKUM - 1
PRAKTIKUM - 2
PRAKTIKUM - 3
PRAKTIKUM - 4
PRAKTIKUM - 5
PRAKTIKUM - 6
PRAKTIKUM - 7
UJI COBA UJIAN SERTIFIKASI INTERNASIONAL
JAWABAN SOAL UJI COBA UJIAN SERTIFIKASI INTERNASIONAL
DAFTAR SERTIFIKASI INTERNASIONAL JAVA
DAFTAR PUSTAKA
10
229
230
232
232
234
235
243
245
247
251
255
259
263
265
293
295
297
PROFIL PENULIS
iv
vi
ii
Seno Adi Putra adalah dosen tetap di Jurusan Sistem Informasi Fakultas Rekayasa Industri Intitut
Teknologi Telkom. Beliau kelahiran Bandung tahun 1978. Beliau adalah lulusan S1 Jurusan Fisika Intitut
Teknologi Bandung tahun 2001. Kemudian pada tahun 2003 beliau melanjutkan studinya di Jurusan
Teknik Elektro Intitut Teknologi Bandung untuk program studi Teknologi Informasi dan mendapat gelar
Master pada tahun 2005.
Setelah menyelesaikan program S2 nya, penulis aktif sebagai pengajar dan peneliti tentang teknologi
Java di Java Competency Center ITB sampai dengan tahun 2009. Pengajaran yang pernah dilakukan
selama aktif di Java Competency Center ITB meliputi :
1.
Pelatihan Fundamentals of Java Programming SL-110 dan Java Programming Language SL-275
untuk program pelatihan reguler di Java Competency Center ITB baik untuk mahasiswa maupun
para profesional;
2.
Pelatihan Fundamentals of Java Programming SL-110, Java Programming Language SL-275, dan
Pengembangan Aplikasi Mobile dengan J2ME untuk Para Dosen seluruh perguruan tinggi di
Indonesia dalam rangka persiapan Program Pendidikan Jarak Jauh D3 Teknik Komputer Jaringan
(PJJ D3 TKJ) Departemen Pendidikan Nasional pada tahun 2007.
3.
Pelatihan Fundamentals of Java Programming SL-110 dan Java Programming Language SL-275
program Hibah Kompetensi Institusi Departemen Teknik Elektro ITB tahun 2008.
Pengembangan Generic Platform Multimedia Messaging Service dengan Teknologi Java yang juga
dipublikasikan di seminar Telematics, System, Services, and Application di ITB tahun 2005;
2.
Pengembangan Fitur Multimedia pada Aplikasi Mobile Learning berbasis Java pada Program
Beasiswa Unggulan Bidang Peneliti, Pencipta, Penulis, Seniman, Tokoh, dan Olahragawan Periode I
Tahun Anggaran 2006 di Biro Perencanaan dan Kerja Sama Luar Negeri Departemen Pendidikan
Nasional RI;
3.
Pengembangan Aplikasi Mobile Enterprise Market Report berbasis Java pada Tahun 2007;
4.
Integrasi Aplikasi Jabber Mobile Instant Messaging dengan Aplikasi Mobile Learning pada Program
Riset Unggulan Departemen Riset dan Teknologi RI dengan ITB pada tahun 2008;
Selain pengajaran dan penelitian, penulis juga pernah menyusun buku ajar atau modul training sebagai
berikut :
1.
Buku ajar Pemrograman Berorientasi Obyek I, Pemrograman Berorientasi Obyek II, dan
Pemrograman Aplikasi Bergerak untuk Program Pendidikan Jarak Jauh D3 Teknik Komputer
Jaringan (PJJ D3 TKJ) yang diadakan oleh Departemen Pendidikan Nasional;
2.
Modul training Membangun Graphical User Interface dan Koneksi ke Database dengan Java (GUI
dan JDBC) dan modul Pengembangan Aplikasi Mobile dengan Teknologi Java 2 Micro Edition (J2ME)
dalam rangka pengembangan materi pelatihan di Java Competency Center ITB.
Penulis juga pernah menjadi konsultan dan pengembang piranti lunak untuk beberapa perusahaan
seperti :
1. Pengembang Aplikasi On-Line Foreign Exchange yang merupakan kerja sama antara PT. Megawastu
dengan Java Competency Center ITB pada Tahun 2005 2006;
2. Konsultan IT Assessment di Kepolisian Republik Indonesia Tahun 2005;
3. Konsultan Perencanaan Strategis Teknologi Informasi Bank Maluku Pada Tahun 2008;
4. Konsultan Perencanaan Strategis Teknologi Informasi Bank Sulteng Pada Tahun 2008;
5. Pengembang Aplikasi Manajemen Risiko Bank untuk Bank Papua Tahun 2008;
6. Pengembang Aplikasi Manila Skyway Project Monitoring and Control System di PT. Prosys Bangun
Persada pada Tahun 2008 - 2009 .
11
vii
12
1
1.4
Pendahuluan
Piranti lunak adalah satu bagian tak terpisahkan dari sistem komputer saat ini. Perkembangan teknologi
komputer saat ini dapat dipastikan mengikutsertakan perkembangan piranti lunak.
Perkembangan pembangunan piranti lunak mengalami kemajuan yang signifikan sejak 6 dekade
terakhir : dimulai dari sekedar memberi instruksi biner ke sistem komputer sederhana, pembuatan
bahasa pemrograman tingkat rendah, tingkat menengah sampai tingkat tinggi. Selain itu, karena
semakin kompleksnya kebutuhan akan komputer sebagai alat bantu komputasi, perkembangan piranti
lunak juga telah melahirkan konsep-konsep pemrograman, mulai dari konsep pemrograman sederhana
(hanya menuliskan baris-baris program dari yang berjalan dari awal sampai akhir program), pembuatan
prosedur-prosedur, sampai pada pemrograman berorientasi obyek.
Pemrograman berorientasi obyek merupakan konsep pemrograman yang relatif baru, di mana
pemrograman diarahkan ke paradigma pembentukan obyek-obyek yang saling berinteraksi. Selain
konsepnya lebih mudah dicerna oleh pemrogram, baik yang awam sekalipun, konsep pemrograman
berorientasi obyek mempermudah pemeliharaan piranti lunak sehingga piranti lunak menjadi lebih
fleksibel apabila akan direvisi atau dikembangkan.
1.5
Pemrograman
Pemrograman merupakan proses "penanaman" instruksi ke dalam komputer sedemikian rupa sehingga
dalam operasinya, komputer tersebut akan mengacu kepada instruksi yang telah diberikan.
Proses pemrograman akan menghasilkan suatu produk yang disebut "program". Program yang berbeda
akan menyebabkan komputer memberikan hasil yang berbeda untuk suatu input yang sama.
Contohnya, anggap saja kita mempunyai 2 buah program Java sebagai berikut :
a.
Penjumlahan.class, yaitu suatu program yang akan menjumlahkan 2 buah input yang diberikan
kepadanya, dan mencetaknya ke layar monitor.
b.
Perkalian.class, yaitu suatu program yang akan mengalikan 2 buah input yang diberikan kepadanya,
dan mencetaknya ke layar monitor.
Misalnya kita memasukkan pasangan 2 buah input { 1, 5 } ke dalam masing-masing program. Maka :
a.
b.
1.5.1
Bahasa Pemrograman
Instruksi yang diberikan kepada komputer pada dasarnya adalah instruksi berupa binary code, yaitu
rangkaian kode-kode biner (yang terdiri atas bilangan-bilangan "0" dan "1" ) yang dapat "dimengerti"
oleh komputer. Instruksi biner yang dapat "dimengerti" oleh komputer adalah instruksi yang memiliki
relasi dengan operasi elementer yang dapat dilakukan oleh komputer, misalnya operasi "menyimpan 1
byte ke alamat tertentu pada memory", "memutar hard-disk", dan sebagainya. Setiap operasi pada
komputer memiliki kode biner tertentu.
Pada perkembangan awal sistem komputer, para pemrogram (programmer) komputer melakukan
pemrograman dengan cara memasukkan nilai-nilai biner ke dalam memory komputer. Nilai-nilai biner
13
yang dimasukkan menggambarkan algoritma dari operasi yang harus dilakukan oleh komputer. Cara ini
memiliki beberapa kesulitan, antara lain :
a.
sebelum memasukkan kode biner yang benar, programmer harus melakukan pengecekan terhadap
pemetaan kode biner tersebut dengan operasi komputer yang diinginkan;
b. ketika terjadi error, programmer harus melakukan kerja ekstra berupa pengecekan kode yang salah
dan pemetaan-ulang terhadap hubungan antara kode biner dengan operasi komputer.
Seiring dengan semakin berkembangnya arsitektur komputer dan semakin banyaknya operasi yang
dapat dilakukan komputer, methode penanaman instruksi dengan menggunakan binary code mulai
dirasakan tidak praktis, karena sulit diterjemahkan ke dalam bahasa manusia. Oleh karena itu dibuatlah
suatu perangkat yang dapat mengkonversi instruksi dari instruksi yang dimengerti oleh bahasa manusia
menjadi instruksi yang dimengerti oleh mesin / komputer. Sebagai contoh :
a.
b.
Dari sini mulai muncul istilah "piranti lunak" yang pada intinya merupakan satu perangkat yang
berperan sebagai pengatur eksekusi operasi-operasi pada komputer.
Piranti lunak-piranti lunak yang dibuat sampai saat ini ditulis dengan menggunakan "bahasa
pemrograman". Bahasa pemrograman dapat didefinisikan sebagai satu kumpulan pola-pola instruksi
yang dapat dimengerti oleh manusia, yang digunakan untuk menulis program / aplikasi / piranti lunak
untuk menghasilkan operasi tertentu pada komputer.
1.5.2
Pengertian "bahasa yang dapat dimengerti oleh manusia" sebenarnya merupakan pengertian relatif.
Bagi programmer-programmer binary code, baris code "..1001100101011..." mungkin dapat
dimengerti. Tetapi bagi programmer-programmer yang terbiasa dengan mnemonic , baris code seperti
"MOV A,#25" masih dapat dimengerti. Dan bagi programmer-programmer Java, baris code seperti
"String s = new String("Hello World");" lebih dapat dimengerti daripada binary atau mnemonic.
Di sini muncul pemeringkatan ( levelling ) bahasa pemrograman. Bahasa pemrograman yang lebih
rendah merupakan bahasa yang "cenderung lebih dimengerti oleh komputer". Sedangkan bahasa yang
lebih tinggi merupakan bahasa yang "cenderung lebih dimengerti oleh manusia". Terdapat beberapa
tingkat bahasa pemrograman, antara lain :
a.
b.
c.
d.
bahasa tingkat rendah ( low-level language ), misalnya bahasa mesin ( binary ), dan assembler;
bahasa tingkat menengah ( medium-level language ), misalnya bahasa C / C++, Fortran.;
bahasa tingkat tinggi ( high-level language ), misalnya bahasa Pascal;
bahasa tingkat lebih tinggi ( higher-level language ), misalnya bahasa Java, DotNet.
Ciri khas dari bahasa yang levelnya lebih rendah adalah kemampuan user untuk memanipulasi operasi
pada level hardware ( misalnya, mengisi, mengedit, dan menghapus data pada memory dan register )
lebih tinggi. Sedangkan pada bahasa yang levelnya lebih tinggi, kemampuan user untuk memanipulasi
operasi pada level hardware lebih rendah. Bahkan pada bahasa higher-level seperti Java, user benarbenar tidak dapat melakukan manipulasi pada level hardware secara langsung, karena operasi-operasi
pada hardware ( misalnya pengalokasian memory, penghapusan data pada memory ) sudah dilakukan
secara otomatis oleh Java Virtual Machine (JVM).
1.5.3
Teknologi Java merupakan salah satu teknologi yang saat ini berkembang pesat dalam waktu yang
sangat singkat. Penerimaan Java yang meluas ini mencerminkan kekuatan dan fitur teknis Java yang
handal. Karakteristik Java meliputi : platform yang netral, dinamis, Berorientasi objek, penghapusan
objek secara otomatis, keamanan yang tinggi, dan handal. Bahasa Pemrograman Java telah menjadi
bahasa pemrograman yang memiliki banyak kegunaannya. Java library mendukung pengembangan
aplikasi dalam berbagai platform.
14
Teknologi Java menawarkan solusi dalam berbagai platform mulai dari platform untuk aplikasi desktop
(Java Standard Edition, J2SE), platform aplikasi enterprise (Java Enterprise Edition, J2EE), hingga
aplikasi mobile (Java Micro Edition, J2ME).
Para pengembang piranti lunak telah mengadopsi Java bukan sekedar untuk suatu pekerjaan
pengembangan aplikasi, tapi juga cukup menyenangkan dan praktis. Java menghilangkan sesuatu yang
membosankan dan meminimalisir kesalahan terus menerus pada pengembangan aplikasi. Java
memberikan para pengembang untuk memusatkan seluruh energinya pada rancangan dan funsionalitas
program.
Prinsip Java adalah "Keep it simple! dan "Keep it learnable!". Dalam artian bahwa Java merupakan
bahasa yang mudah dipelajari karena kesederhanaannya. Oleh karena itu, saat ini telah banyak yang
menggunakan Java mulai dari kalangan pelajar, programmer, pengembang, dan praktisi IT dalam
pembangunan perangkat lunaknya.
1.6
Pembuatan piranti lunak dilakukan melalui tahapan-tahapan yang membentuk suatu siklus hidup. Siklus
hidup ini terdiri dari 6 tahap, yaitu analisis, disain, pengembangan, pengujian, pemeliharaan, dan tahap
akhir siklus. Penjelasan tentang keenam langkah tersebut dijelaskan pada bagian lain dari bab ini.
1.6.1
Analisis
Langkah pertama yang dilakukan dalam Analisis adalah proses investigasi terhadap masalah yang akan
dipecahkan melalui produk/program yang akan dihasilkan. Pada tahap Analisis terdapat 2 hal yang
harus dilakukan, antara lain :
a.
b.
mendefinisikan permasalahan yang akan dipecahkan, pangsa pasar yang akan diambil, atau sistem
yang akan dibuat. Proses ini disebut scoping.
mengidentifikasi komponen/sub-komponen inti yang akan menjadi komponen dasar bagi produk
yang akan dihasilkan.
15
Gambar 1.2 memperlihatkan ilustrasi bahwa ketika pengembang piranti lunak mempunyai suatu
permasalahan/ide, harus dilakukan identifikasi terhadap komponen-komponen dasar dari produk yang
akan dihasilkan.
1.6.2
Disain
Disain adalah implementasi hal-hal yang telah dianalisis dalam fase Analisis, misalnya menentukan
komponen-komponen penyusun produk ke dalam suatu cetak biru/blueprint. Fase ini menghasilkan :
a.
b.
Pada Gambar 1.3, komponen-komponen inti (Major Components) yang telah diidentifikasi pada fase
analisis dimasukkan ke dalam disain menjadi sebuah cetak biru utama (Master Blueprint). Pada cetak
biru utama, didefinisikan pula spesifikasi dari setiap komponen tersebut, sehingga menjadi cetak-biru
beberapa komponen (Component Blueprints) yang memiliki pola spesifikasi yang lebih jelas.
1.6.3
Pengembangan (Development)
Fase pengembangan merupakan rangkaian aktivitas penggunaan cetak-biru komponen untuk membuat
komponen-komponen aktual. Dalam prakteknya, dapat saja cetak-biru komponen tersebut
direalisasikan dengan membuat sub-sub komponen. Ilustrasi mengenai fase pengembangan dapat
dilihat pada Gambar 1.4.
1.6.4
Pengujian (Testing)
Pengujian adalah proses evaluasi atas komponen-komponen sampai kepada sistem secara keseluruhan
apakah memenuhi kebutuhan yang diinginkan (sesuai dengan spesifikasi yang diharapkan).
16
Unit Testing, yaitu pengujian atas semua komponen / sub-komponen penyusun produk. Hal-hal
yang diuji misalnya kesesuaian output yang dihasilkan dengan output yang diharapkan,
kemampuan komponen untuk meminimalisasi bug ( gangguan ), kemampuan komponen untuk
mengantisipasi input yang tidak sesuai (misalnya jika input diharuskan berupa bilangan, ternyata
yang dimasukkan oleh user adalah huruf ).
b.
Functional Testing, yaitu pengujian atas kesesuaian fungsi yang dihasilkan oleh komponenkomponen dengan fungsi yang diinginkan. Misalnya jika sebuah komponen diharapkan dapat
melakukan perhitungan "pendapatan bersih" yang merupakan hasil pemotongan-pemotongan
terhadap "pendapatan kotor", maka functional testing atas komponen tersebut akan sukses jika
komponen tersebut dapat menghasilkan hasil perhitungan yang benar.
c.
Flow Graph Testing, yaitu pengujian alur proses pada prototype/produk yang dihasilkan. Testing ini
bertujuan menguji kesesuaian antara event dengan perpindahan state.
d.
Performance Testing, yaitu pengujian kinerja proses-proses yang dijalankan oleh prototype/
produk. Kinerja diukur berdasarkan parameter-parameter yang ditetapkan sebelumnya, misalnya
kecepatan proses, efisiensi penggunaan memory, dan lain-lain.
e.
Security Testing, yaitu pengujian keamanan sistem. Biasanya pengujian ini dilakukan jika spesifikasi
produk mensyaratkan adanya pembatasan hak akses atas sekumpulan data.
f.
1.6.5
Implementasi ( Implementation )
Implementasi adalah proses penerapan produk sehingga dapat digunakan oleh user. Proses ini terdiri
atas beberapa langkah, antara lain :
a.
b.
Pelatihan kepada user dengan tujuan user dapat menggunakan produk tersebut.
Catatan : Fase implementasi kadang-kadang dilakukan paralel dengan pengujian, terutama untuk
memastikan kompatibilitas / kesesuaian produk jika diinstalasi di sistem milik user.
17
1.6.6
Pemeliharaan (Maintenance)
Pemeliharaan terdiri atas proses-proses perbaikan terhadap masalah-masalah yang terjadi pada
produk. Pemeliharaan terhadap produk dapat berupa :
a.
b.
c.
d.
e.
Perbaikan bug
Re-install produk ke sistem komputer
Back-up data
Perbaikan pada komponen-komponen
dan lain-lain.
1.6.7
Fase EOL ini mencakup proses-proses yang mengumpulkan kesimpulan dan permintaan user terhadap
produk yang telah berjalan di sistem. Hasil feedback ini dapat menghasilkan keputusan untuk
memodifikasi produk sehingga dihasilkan versi-versi produk yang lebih mutakhir dan lebih dapat
memenuhi kebutuhan user.
18
2
2.7
ANALISIS MASALAH
BERORIENTASI OBYEK
Pendahuluan
Pada bab ini, akan dibahas cara menganalisis suatu masalah dengan menggunakan konsep analisis
berbasis obyek (Object-Oriented Analysis). Analisis masalah akan menghasilkan cetak-biru dari
komponen-komponen pembentuk obyek.
2.8
Contoh Masalah
Contoh masalah yang akan dibuat desain pemecahannya adalah sebagai berikut :
a.
sebuah koperasi menginginkan sebuah aplikasi pelaporan rekapitulasi stok barang yang mencatat
persediaan, pemasukan dan pengeluaran barang. Laporan ini dilakukan seminggu sekali;
b.
aplikasi ini akan dijalankan oleh seorang petugas khusus logistik. Petugas tersebut akan mencatat
Stok barang didapat dari supplier-supplier, baik dari dalam maupun luar kota. Penjualan barang
dilakukan pada sebuah mini market, yang pembelinya berasal dari anggota koperasi maupun yang
bukan anggota koperasi;
c.
kemudian ada kebijakan kalau barang berupa makanan yang masa kedaluwarsanya sudah lewat,
harus dibuang, dan yang masa kedaluwarsanya tinggal 6 bulan lagi, diberikan diskon 50% (asumsi
makananya semuanya mempunyai masa kedaluwarsa > 1 tahun ). Kebijakan lainnya adalah : untuk
item barang yang tinggal <= 40% persen dari seharusnya, harus segera ditambah stoknya.
2.9
Domain masalah didefinisikan sebagai ruang lingkup permasalahan yang akan dipecahkan. Ruang
lingkup ini membatasi permasalahan sehingga permasalahan tidak meluas, dan tetap pada fokusnya.
Domain masalah ini dapat ditentukan dari permintaan / requirements yang diberikan oleh pihak yang
meminta aplikasi (customer). Setelah permintaan tersebut dikumpulkan, maka developer ( dalam hal ini
programmer ) dapat membuat pernyataan tentang apa yang akan dibuatnya , misalnya : Membuat
sistem pelaporan stok barang pada koperasi yang mengakomodasi kebijakan-kebijakan kedaluwarsa
dan potongan harga .
19
obyek dapat bersifat konseptual atau berupa benda fisik. Untuk masalah Sistem Manajemen Stok
Barang, obyek yang bersifat konseptual misalnya Stok Barang. Sedangkan obyek yang berupa
benda fisik misalnya Barang;
b.
obyek memiliki atribut atau karakteristik. Karakteristik ini berupa data yang dibawa oleh obyek
tersebut. Untuk obyek Stok Barang, karakteristiknya antara lain jumlah barang, nama barang;
c.
obyek memiliki operasi. Operasi ini menggambarkan aktivitas-aktivitas yang dapat dilakukan oleh
obyek ini. Biasanya operasi memberikan efek terhadap karakteristik, yaitu berupa modifikasi nilai.
Misalnya untuk obyek Barang, operasinya adalah : tambahBarang.
Dalam fase ini, kegiatan utamanya adalah mengumpulkan obyek-obyek yang mungkin terlibat
sebanyak-banyaknya. Kemudian daftarkan atribut dan operasi yang dimiliki oleh setiap obyek.
Sebagai contoh, obyek-obyek yang akan diperkirakan akan digunakan dalam memecahkan masalah
dapat dilihat pada Tabel II.1.
Tabel II.1
Obyek yang Diperkirakan Akan
Digunakan Dalam Aplikasi
Obyek
Barang
Supplier
Koperasi
Pembeli
Gudang
Daftar Transaksi
Daftar Stok Barang
20
Atribut
Operasi
jumlah
harga beli
tanggal
kedaluwarsa
harga jual
ID barang
diskon
nama
lokasi
ID supplier
jenis barang
daftar transaksi
gudang
ID pembeli
nama pembeli
.modifikasi ID pembeli
modifikasi nama pembeli
Barang [ ]
jumlahBarang[]
tambah barang
kurangi barang
b.
Apakah obyek tersebut eksis pada batasan-batasan yang ditentukan pada permasalahan ?
Apakah sebuah user dibutuhkan sebagai bagian dari interaksi antara user dan solusi ?
Sekarang akan dicoba memilih obyek-obyek dari daftar obyek yang telah dibuat :
a.
Barang.
Obyek Barang mendeskripsikan informasi tentang barang yang menjadi item yang dijual di
koperasi, seperti jumlah, harga beli, tanggal kedaluwarsa, dll. Karena informasi yang dikandungnya
relevan dengan permasalahan, yang membutuhkan informasi jumlah barang, tanggal kedaluwarsa,
dan harga, maka Barang dapat menjadi obyek utama untuk menyelesaikan masalah.
b.
Supplier.
Obyek Supplier mendeskripsikan informasi tentang supplier barang yang menjadi acuan koperasi
untuk membeli barang, misalnya ID supplier, jenis barang, dll. Menurut spesifikasi desain, supplier
tidak termasuk ke dalam scope masalah, karena masalah lebih banyak berkutat di bagian
penentuan harga barang. Oleh karena itu, obyek Supplier dapat tidak diikutsertakan.
c.
Koperasi.
Obyek Koperasi mendeskripsikan informasi berupa daftar transaksi dan gudang. Kedua informasi
tersebut merupakan obyek-obyek yang memuat informasi tersendiri. Di sini terdapat obyek yang
menjadi atribut obyek lain (Daftar Transaksi dan Gudang menjadi atribut Koperasi). Jika dianalisa
relevansinya dengan permasalahan, kelas Koperasi dibutuhkan sebagai kelas sutama ( main class ),
karena permasalahan yang akan dipecahkan berada pada lingkungan koperasi. Jika dianalisa tingkat
independensinya terhadap kelas lain, terutama yang menjadi atributnya, maka kelas koperasi
memiliki independensi terhadap kelas daftar transaksi.
Tetapi class koperasi memiliki
ketergantungan dengan kelas gudang. Hal ini disebabkan oleh masuknya gudang sebagai atribut
dari koperasi dan masuknya koperasi sebagai atribut dari gudang. Karena antara Koperasi dan
Gudang terdapat ketergantungan, solusinya adalah menghilangkan Gudang dan memasukkan data
yang dimilikinya ke Koperasi, yaitu daftar stok barang.
d.
Pembeli.
Pembeli mendeskripsikan informasi berupa data pembeli yang akan membeli barang dari koperasi.
Data pembeli tersebut adalah ID pembeli dan nama pembeli. Jika dianalisa relevansinya terhadap
permasalahan, kelas Pembeli tidak perlu digunakan, karena permasalahan tidak menyentuh perihal
pencatatan pembeli.
21
e.
Daftar Transaksi.
Daftar transaksi mendeskripsikan informasi berupa data penjualan dan data pembelian. Data
penjualan dan pembelian diperlukan sebagai variabel yang akan mempengaruhi stok barang. Jika
dilihat relevansinya terhadap permasalahan, daftar transaksi ini mempunyai efek langsung
terhadap stok barang. Kemudian pada daftar transaksi tidak terdapat obyek yang merupakan salah
satu obyek yang telah didaftarkan. Jadi, obyek Daftar Transaksi dapat diajukan menjadi obyek yang
terlibat dalam aplikasi.
f.
2.12 Solusi
Setelah obyek-obyek diseleksi, maka didapatlah daftar solusi obyek yang akan digunakan untuk
menyelesaikan masalah, yaitu obyek Barang, Koperasi, Daftar Transaksi dan Daftar Stok Barang, seperti
diperlihatkan pada Gambar 2.1. Perhatikan bahwa pada setiap obyek, terdapat kotak yang
menunjukkan nama obyek (paling atas), nama-nama variabel, dan nama-nama operasi (paling bawah).
BARANG
KOPERASI
jumlah
harga beli
daftar transaksi
tanggal kedaluwarsa
harga jual
ID barang
hitung tanggal kedaluwarsa
DAFTAR TRANSAKSI
data penjualan [ ]
barang []
data pembelian [ ]
jumlah barang []
tambah barang
kurangi barang
22
3
3.2
Kelas adalah cetak-biru dari obyek. Seperti halnya semua cetak-biru dalam kehidupan sehari-hari, kelas
merupakan acuan bagaimana obyek itu dibentuk, data apa saja yang disimpan oleh obyek, dan operasioperasi apa saja yang dapat dilakukan oleh obyek.
Karena pentingnya peran sebuah kelas dalam membangun sebuah aplikasi menggunakan konsep
Pemrograman Berbasis Obyek, maka perlu dipahami struktur dasar dari kelas.
deklarasi kelas;
deklarasi dan inisialisasi atribut;
pendefinisian method;
komentar.
Untuk membuat sebuah obyek, terlebih dahulu harus dilakukan pendeklarasian kelas. Pendeklarasian
kelas dimaksudkan untuk mendefinisikan data-data yang dibawa oleh obyek tersebut, lalu operasioperasi yang dapat dilakukan.
Pada pemrograman Java, pendeklarasian kelas dilakukan dengan menggunakan syntax sebagai berikut :
[modifier] class class_identifier
di mana :
a.
[modifiers] merepresentasikan kata kunci pada teknologi Java yang memodifikasi cara-cara
penggunaan kelas. Contoh : public, protected, private, static, final;
b.
class adalah kata kunci pada teknologi Java, yang mengindikasikan deklarasi sebuah kelas;
c.
Contoh 3.1
public class Barang {
}
Deklarasi variabel dilakukan di dalam kelas. Variabel yang didefinisikan di kelas merupakan atribut dari
kelas tersebut (yang otomatis merupakan atribut dari obyek). Secara rinci pendeklarasian variabel akan
diuraikan pada Bab IV.
Penugasan terhadap variabel merupakan pemberian nilai kepada nilai. Karena dalam deklarasi kelas,
penugasan variabel merupakan penugasan pertama kali, maka penugasan ini dapat juga disebut
inisialisasi variabel. Syntax umum deklarasi dan inisialisasi variabel adalah sebagai berikut :
[modifiers] data_type identifier [ = value ] ;
23
di mana :
a.
[modifiers] merepresentasikan beberapa kata kunci pada teknologi Java, misalnya public, private,
static, dll.
b.
data_type merepresentasikan tipe data dari variabel, misalnya int, String, float, < nama kelas >, dll.
c.
d.
value adalah nilai awal ( inisialisasi ) dari variabel. Pencantuman value ini sifatnya opsional, karena
inisialisasi variabel tidak harus dilakukan bersamaan dengan deklarasi.
Contoh pendeklarasian variabel atribut pada kelas Barang adalah sebagai berikut (Contoh III.2).
Contoh 3.2
import java.util.Date;
public class
public
public
public
public
public
double
}
Barang {
int jumlah ; //contoh deklarasi
int hargaBeli ;
Date tanggalKedaluwarsa ;
int hargaJual ;
String idBarang ;
diskon = 0.0 ; //contoh penugasan
Method merepresentasikan operasi-operasi yang dapat dilakukan oleh obyek. Dalam penulisan, yang
membedakan method dan variabel adalah : method selalu diakhiri dengan ( ) atau (< nama argumen >).
Pendeklarasiannya juga berbeda, yaitu dengan menambahkan blok { ... } dan mengisi blok tersebut
dengan baris-baris program. Bentuk umum penulisan deklarasi method adalah sebagai berikut :
[modifiers] return_type method_identifier ([arguments]){
method_code_block;
}
di mana :
a.
[modifiers] merepresentasikan kata kunci pada teknologi Java yang memodifikasi cara-cara
penggunaan method. Contoh : public, protected, private, static, final.
b.
return_type adalah tipe nilai yang akan dikembalikan oleh method yang akan digunakan pada
bagian lain dari program. Return_type pada method sama dengan tipe data pada variabel.
Return_type dapat merupakan tipe data primitif maupun tipe data referensi.
c.
d.
e.
Contoh pendefinisian method pada class Barang ditunjukkan pada Contoh III.3.
24
Contoh 3.3
public class Barang {
... //inisialisasi variabel
public void setIDBarang( String id ){
idBarang = id;
}
}
Pemberian komentar dilakukan untuk menandai baris-baris program tertentu dengan beberapa
catatan. Catatan ini biasanya berisi maksud dari baris program tersebut, atau keterangan lainnya.
Pemberian komentar dimaksudkan agar di kemudian hari, ketika program membutuhkan perbaikan,
programmer ( baik programmer yang membuat program pertama kali maupun penggantinya ) tidak
mengalami kesulitan dalam menganalisis maksud dari baris program tersebut.
Pemberian komentar dapat dilakukan dengan 2 macam syntax, yaitu :
a.
Pada awal baris yang dikomentari ditulis : /* ..... (komentar) , lalu pada akhir baris yang dikomentari
ditulis : (komentar) ..... */. Contoh :
/* ini variabel untuk menyimpan
data harga jual */
public int hargaJual ;
Masuklah ke dalam situs http://www.java.sun.com, maka akan muncul tampilan situs Sun
Developer Network 9 SDN ) seperti pada Gambar 3.1 (tampilan per 6 Februari 2007).
25
b.
Kliklah pada bagian Popular Download : Java SE. Maka akan terlihat tampilan Java SE Downloads
seperti pada Gambar 3.2.
c.
Kemudian klik-lah tab Downloads. Anda akan masuk ke dalam halaman Sun Downloads yang berisi
file-file open source Java yang dapat didownload ( Gambar 3.3 ).
d.
Pada halaman Sun Downloads terdapat notifikasi untuk menyetujui agreement untuk mendownload file-file dari Sun Microsystems, yang berbunyi :
Klik Review License Agreement. Agreement tersebut lebih banyak membahas masalah penyebaran
source. Jika merasa tidak perlu membaca License Agreement, klik saja radio button Accept License
Agreement.
e.
26
Halaman akan refresh dalam beberapa detik, dan kemudian Anda dapat mendownload Sun
Development Kit ( SDK ) yang sudah termasuk di dalamnya Java Runtime Environment ( JRE ). Jika
Anda menggunakan sistem operasi Windows, carilah Windows Platform - Java (TM) SE
Development Kit 6 ( lihat Gambar 3.4 ).
f.
Kliklah Windows Offline Installation, Multi-language. Offline installation maksudnya adalah anda
akan mendownload dahulu file installer yang lengkap ( jdk-6-windows-i586.exe ), baru kemudian
Anda menginstall dari komputer ( PC / laptop ) anda. Maka akan muncul message box seperti pada
Gambar 3.5.
g.
Klik Save, lalu pilih pada folder mana akan Anda simpan file jdk-6-windows-i586.exe tersebut.
h.
Download dimulai.
Setelah di-download, maka langkah berikutnya adalah melakukan instalasi. Langkah-langkahnya adalah
sebagai berikut :
a.
Double-click file jdk-6-windows-i586.exe. Maka akan keluar tampilan seperti pada Gambar 3.6.
b.
Kemudian akan muncul konfirmasi License Agreement, seperti pada Gambar 3.7.
Klik radio button I accept the terms in the license agreement. Lalu klik Next.
27
c.
Kemudian akan muncul halaman Custom Setup seperti pada Gambar 3.8.
Klik Change... jika Anda ingin mengubah lokasi instalasi. Setelah Anda sudah menentukan lokasi
instalasi, maka klik Next.
d.
Setelah itu, instalasi dilakukan secara otomatis, seperti terlihat pada Gambar 3.9.
e.
Hasil instalasi adalah sebuah sebuah folder j2sdk.1.6 dengan berbagai sub-folder, antara lain :
a)
/bin
b) /lib
c)
/jre
d) /include
Sementara ini yang dianggap penting adalah folder /bin. Sebab pada folder /bin terdapat file
executable yang digunakan untuk kompilasi, yaitu javac.exe dan file executable yang digunakan
untuk eksekusi, yaitu java.exe.
Setelah Java 2 Standard Edition diinstalasi, maka langkah berikutnya adalah melakukan setting path.
Path diperlukan supaya ketika perintah kompilasi ( javac ) dan perintah eksekusi ( java ) dijalankan dari
lokasi manapun pada file system , maka system akan melacak referensi perintah tersebut melalui path
yang telah di-setting . Jika Anda menggunakan sistem operasi Windows XP, maka langkah-langkah
setting path adalah sebagai berikut:
28
a.
Pada desktop, klik Start, lalu klik-kanan My Computer, lalu klik Properties. Maka akan muncul frame
System Properties, seperti pada Gambar 3.10.
b.
Klik tab Advanced pada frame System Properties. Akan muncul beberapa pilihan seperti pada
Gambar 3.11.
c.
Klik Environment Variables. Maka akan terlihat frame Environment Variables yang terdiri atas
variabel-variabel user dan variabel-variabel sistem. Variabel-variabel user adalah variabel yang
bersesuaian dengan user. Variabel ini akan aktif ketika user yang login sesuai dengan peruntukan
variabel tersebut. Sedangkan variabel system adalah variabel yang berlaku siapapun yang
melakukan login ke sistem. Lihat Gambar 3.12.
29
d.
Jika pada System Variables terdapat variabel Path, klik Edit, lalu tambahkan pada bagian belakang (
misalnya file j2sdk berada pada c:\ j2sdk)
Lakukan restart komputer Anda. Maka setelah dilakukan restart maka kita dapat memanggil
perintah javac dan java dari berbagai lokasi di file system. Dengan demikian, semua tahapan
persiapan sudah selesai sampai di sini.
Setelah konfigurasi dan instalasi J2SDK dilakukan, selanjutnya program Java yang telah dibuat dapat
dikompilasi dan dijalankan. Pada Contoh III.4, akan dibuat sebuah aplikasi sederhana yang akan
menampilkan semua atribut dari kelas Barang. Aplikasi ini terdiri atas 2 kelas, yaitu :
a.
kelas Barang, yaitu class yang menyimpan data-data barang. Class ini disimpan pada file
dengan nama yang sama dengan nama class tersebut, yaitu : Barang.java;
b.
kelas DisplayBarang, yaitu kelas utama yang menampilkan data-data yang disimpan oleh kelas
Barang. Kelas ini disimpan pada file dengan nama yang sama dengan nama kelas, yaitu :
DisplayBarang.java.
Contoh 3.4
public class
public
public
public
public
double
Barang {
int jumlah ; //contoh deklarasi
int hargaBeli ;
int hargaJual ;
String idBarang ;
diskon = 0.0 ; //contoh penugasan
30
b.
Klik Run...
c.
Pada DOS prompt, masuk ke folder C:\Latihan> , jika Anda menyimpan file-file latihan Anda di
folder tersebut. Jika tidak, masuklah ke folder latihan buatan Anda sendiri.
d.
e.
Jika setelah ditekan Enter, kemudian muncul prompt lagi ( misalnya : C:\Latihan> ), maka proses
kompilasi sukses.
f.
Cek pada folder yang sama, apakah file Barang.class sudah terbentuk. Ketiklah :
C:\Latihan>dir
g.
h.
Lakukan pula kompilasi untuk file DisplayBarang.java dengan langkah yang sama seperti langkah d.
Setelah file-file *.java dikompilasi, maka file-file hasil kompilasi (*.class) siap dieksekusi. File yang dapat
dipanggil untuk dieksekusi adalah file yang berisi method main( ). Dalam hal ini adalah file
DisplayBarang.class. Prosedur eksekusi programnya adalah sebagai berikut :
a.
b.
Klik Run...
c.
Pada DOS prompt, masuk ke folder C:\Latihan> , jika Anda menyimpan file-file latihan Anda di
folder tersebut. Jika tidak, masuklah ke folder latihan buatan Anda sendiri.
d.
e.
31
EKSPERIMEN
1. Deklarasikan 2 buah kelas bebas pada satu file dengan masing-masing kelas memiliki
variabel-variabel atribut (minimal 1 buah), dan tiap-tiap kelas mempunyai modifier
public, misalnya salah satunya adalah:
Berilah nama file tersebut dengan nama salah satu kelas, misalnya Barang.java.
Lakukan kompilasi. Apa yang terjadi ?
2. Kemudian salah satu kelas yang nama kelasnya bukan nama File, modifiernya
dijadikan private, misalnya :
Simpan perubahan pada file dengan nama file yang sama dengan nama kelas yang
bermodifier public.
Lakukan kompilasi. Apa yang terjadi ?
32
DEKLARASI, INISIALISASI,
DAN PENGGUNAAN VARIABEL
Contoh 4.1
public class Mobil{
//deklarasi dan inisialisasi variabel anggota
public String noPol = D 234 LE;
public String merk = Suzuki Escudo;
public int harga = 70000000;
public int tahunPembuatan = 1999;
public String namaPemilik = Sutrisno;
//akhir deklarasi dan inisialisasi variabel anggota
//definisi method tampilkanInfoMobil( )
public void tampilkanInfoMobil( ){
//menampilkan Nomor Polisi
System.out.println(Nomor Polisi : + noPol);
//menampilkan Merk
System.out.println(Merk : +merk);
//menampilkan Harga
System.out.println(Harga : +harga);
//menampilkan Tahun Pembuatan
System.out.println(Tahun Pembuatan : +tahunPembuatan);
//menampilkan Nama Pemilik
System.out.println(Nama Pemilik + namaPemilik);
}//akhir dari method tampilkanInfoMobil
//main method
public static void main ( String[ ] args ){
//instanstiasi obyek mobil1
Mobil mobil1 = new Mobil ( );
//perintah untuk menampilkan data tentang mobil1
mobil1.tampilkanInfoMobil( );
}
}//akhir dari class
Pada Contoh 4.1 diberikan contoh class Mobil. Class ini memiliki variabel anggota ( member variables ),
yaitu :
a.
b.
c.
d.
e.
noPol, bertipe data String, digunakan untuk menyimpan data nomor polisi dari mobil;
merk, bertipe data String, digunakan untuk menyimpan data merek mobil;
harga, bertipe data int, digunakan untuk menyimpan data harga mobil;
tahunPembuatan, bertipe data int, untuk menyimpan data tahun pembuatan mobil;
namaPemilik, bertipe data String, untuk menyimpan data nama pemilik mobil.
33
b.
variabel instans / instance variables, karena variabel-variabel ini akan di-copy ke dalam variabelvariabel yang akan menjadi milik eksklusif dari sebuah instans / obyek, yang otomatis memberikan
informasi tentang obyek yang menjadi pemiliknya.
Salah satu penggunaan variabel adalah dalam keperluan mencetak data, seperti pada baris berikut pada
contoh kode program 4.1. :
//menampilkan Nomor Polisi
System.out.println(Nomor Polisi : + noPol);
//menampilkan Merk
System.out.println(Merk : +merk);
nilai variabel noPol dan merk akan tercetak pada layar monitor sebagai berikut:
Nomor Polisi : D 234 LE
Merk : Suzuki Escudo
Pada contoh 4.1, semua perintah mencetak pada method tampilkanInfoMobil( ) akan mengambil nilai /
data dari variabel-variabel atribut yang telah didefinisikan di kelas Mobil. Agar nilai dapat diambil,
maka harus dideklarasikan terlebih dahulu variabel tempat menyimpan nilai tersebut. Sintak umum
deklarasi dan inisialisasi adalah sebagai berikut :
[modifiers] merepresentasikan beberapa kata kunci pada teknologi Java, misalnya public, private,
static, dan lainnya;
b.
data_type merepresentasikan tipe data dari variabel, misalnya int, String, float, < nama class >, dan
lainnya;
c.
d.
value adalah nilai awal ( inisialisasi ) dari variabel. Pencantuman value ini sifatnya opsional, karena
inisialisasi variabel tidak harus dilakukan bersamaan dengan deklarasi.
Contoh 4.2
public class Mobil{
//definisi method tampilkanInfoMobil( )
public void tampilkanInfoMobil( ){
//menampilkan Nomor Polisi
System.out.println(Nomor Polisi : + noPol);
//menampilkan Merk
System.out.println(Merk : +merk);
//menampilkan Harga
System.out.println(Harga : +harga);
//menampilkan Tahun Pembuatan
System.out.println(Tahun Pembuatan : +tahunPembuatan);
//menampilkan Nama Pemilik
System.out.println(Nama Pemilik +namaPemilik);
}//akhir dari method tampilkanInfoMobil
34
//main method
public static void main ( String[ ] args ){
//instanstiasi obyek mobil1
Mobil mobil1 = new Mobil ( );
//perintah untuk menampilkan data tentang mobil1
mobi1.tampilkanInfoMobil( );
}
} //Akhir Kelas
Misalnya kelas Mobil hanya berisi method tampilkanInfoMobil( ) saja, seperti pada Contoh 4.2, maka
ketika dilakukan kompilasi, maka program akan mengalami kegagalan kompilasi, dan JVM akan
mengeluarkan pesan error sebagai berikut:
Pesan error berupa cannot resolve symbol, berarti sistem tidak mengenali simbol-simbol tertentu, yang
dalam kasus ini simbol-simbol tersebut adalah variabel-variabel noPol, merk, harga, tahunPembuatan,
dan namaPemilik. Hal ini dikarenakan JVM tidak menemukan referensi yang menjelaskan jenis simbol
(kelas/variabel/obyek), dan tipe datanya (primitif/referensi). Simbol-simbol tersebut belum
didefinisikan sebelumnya.
Proses pendefinisian variabel dinamakan deklarasi. Secara teknis, deklarasi berarti perintah kepada
sistem ( JVM ) untuk mengalokasikan satu blok memori dengan ukuran tertentu ( besarnya dalam byte,
tergantung dari type datanya ). Contoh deklarasi variabel dapat dilihat pada penggalan baris berikut ini :
...
public String noPol;
...
public int harga;
...
public void tampilkanInfoMobil( ){
noPol = D 234 LE;
harga = 70000000;
...
}
35
contoh tersebut merupakan variasi dari Contoh 4.1 dengan penambahan baris yang mendeklarasikan
variabel bernama noPol dideklarasikan dengan tipe data String. Artinya, JVM akan
mengalokasikan satu blok memori yang akan merujuk ke suatu kumpulan blok memori yang akan
menampung data String (data String merupakan kumpulan data karakter). Pada penggalan kode
tersebut juga dideklarasikan sebuah variabel harga dengan tipe data int, artinya JVM akan
mengalokasikan satu blok memori yang akan digunakan sebagai media penyimpanan nilai untuk
variabel harga.
Inisialisasi variabel adalah pernyataan/statement pemberian nilai awal variabel setelah variabel
tersebut dideklarasikan. Secara teknis, inisialisasi variabel berarti memasukkan suatu nilai ke memori
yang dialokasikan untuk variabel tersebut. Pada contoh penggalan kode program di atas, proses
inisialisasi variabel dilakukan pada method tampilkanInfoMobil(). Untuk tipe data String,
nilainya dinyatakan dalam tanda kutip ....
EKSPERIMEN
Deklarasi dan inisialisasi variabel dapat dilakukan sekaligus. Contoh penggalan kode berikut
memperlihatkan proses deklarasi yang dilakukan sekaligus dengan memasukkan nilai awal (inisialisasi)
ke variabel yang dideklarasikan.
...
public String noPol = D 234 LE;
...
public int harga = 70000000;
Pada penggalan kode program di atas, variabel noPol dideklarasikan sebagai variabel tipe String,
dengan nilai awal adalah D 234 LE. Pada baris selanjutnya, variabel harga dideklarasikan sebagai
variabel tipe int dengan nilai awal adalah 70000000. Cara deklarasi dan inisialisasi variabel sekaligus
ini dapat diterapkan di luar method. Berbeda dengan cara pertama, di mana inisialisasi yang berada
pada statement yang terpisah dengan deklarasi harus dilakukan di dalam method.
36
Berikut akan dibahas tipe data primitif, yaitu tipe data yang digunakan untuk variabel yang nilainya
ditempatkan pada alokasi memori yang telah ditentukan. Tipe data yang lain adalah tipe data referensi,
yaitu tipe data yang digunakan untuk variabel yang alokasi memorinya memuat referensi ke alamat
memori lain, bukan memuat nilai. Nilai sesungguhnya berada di memori lain yang ditunjuk.
Terdapat beberapa jenis tipe data primitif, antara lain :
a.
b.
c.
d.
Integral, merepresentasikan nilai-nilai bilangan bulat ( tidak memiliki elemen pecahan desimal.
Floating point, merepresentasikan nilai-nilai bilangan real ( memiliki elemen pecahan desimal )
Tekstual, merepresentasikan nilai-nilai berupa alphabet.
Logika, merepresentasikan nilai-nilai logika ( hanya bernilai true dan false ).
Tipe data integral merupakan tipe data untuk variabel yang nilai-nilainya adalah bilangan bulat ( tidak
memiliki elemen pecahan desimal ). Ada 4 tipe data yang merupakan tipe data integral. Masing-masing
diperlihatkan pada Tabel IV.1.
Tabel IV.1.
Tipe Data Integral
Tipe
Data
byte
short
int
long
Panjang
8 bit
16 bit
32 bit
64 bit
Rentang Nilai
7
-2 sampai 2
(-128 sampai 127 )
(256 kemungkinan nilai)
15
15
-2 sampai 2
(-32.768 sampai 32.767)
(65.535 kemungkinan nilai)
31
31
-2 sampai 2
( -2.147.483.648 sampai 2.147.483.647)
(4.294.967.296 kemungkinan nilai)
-63
63
-2 sampai 2
( -9.223.372.036.854.775.808 sampai
9.223.372.036.854.775.807)
(18.446.744.073.709.551.616 kemungkinan
nilai)
Contoh Nilai
5
-126
9
-23659
2067456397
-1456398567
3L
-2147483648L
67L
37
Pada Tabel IV.1, terlihat bahwa masing-masing tipe data integral mempunyai panjang representasi
biner yang berbeda, mulai dari 8 bit (tipe byte ), sampai 64 bit (tipe long). Perbedaan representasi biner
ini berpengaruh pada rentang nilainya. Untuk menyatakan nilai variabel bertipe long, perlu
ditambahkan huruf L di belakang angka. Tipe data integral memiliki 1 sign bit yang menempati bit
dengan urutan tertinggi ( byte : bit ke-7, short : bit ke-15, int : bit ke-31, long : bit ke-63 ). Gambar 4.1
memperlihatkan representasi biner dari setiap tipe data, dengan menampilkan representasi untuk
bilangan maksimum dan minimum.
Tipe data floating point merupakan tipe data untuk untuk variabel yang nilai-nilainya adalah bilangan
real (dapat mempunyai pecahan desimal). Tabel IV.2 memperlihatkan 2 jenis tipe data floating-point,
yaitu float dan double.
Tabel IV.2
Tipe Data Floating-Point
Tipe
Data
Panjang
float
32 bit
double
64 bit
Tipe data textual merupakan tipe data untuk variabel yang nilai-nilainya adalah karakter tunggal. Tipe
data yang merupakan tipe data textual adalah char yang memiliki panjang 16 bit. Nilai variabel char
ditulis dengan diberi tanda kutip tunggal .... Berikut contoh penggunaan tipe data char :
Perhatikan jenis data yang akan digunakan dalam program, apakah berupa bilangan bulat, bilangan
real, nilai logika, atau karakter. Sesuaikan tipe data dengan kebutuhan jenis data tersebut.
b.
Perhatikan dalam rancangan program, apakah terdapat operasi pembagian. Ketika terdapat operasi
pembagian, sangat disarankan menggunakan variabel dari jenis data yang mengakomodasi
bilangan real, supaya tidak terjadi loss of precision.
c.
Untuk program-program yang memperhatikan ukuran memory, seperti aplikasi mobile phone,
pemilihan data dengan ukuran yang lebih kecil lebih direkomendasikan, misalnya byte, short, float.
38
Supaya data dapat digunakan dalam operasi-operasi pada program, maka perlu didefinisikan alokasi
memori yang dibutuhkan untuk menyimpan data tersebut. Pendefinisian alokasi memori tersebut
dinamakan deklarasi.
Variabel pada dasarnya adalah alokasi memori. Masalah akan timbul apabila terdapat beberapa alokasi
memori yang dapat diisikan data. Data harus dialokasikan ke alokasi memori yang tepat. Oleh karena
itu, selain alokasi memori, dibutuhkan juga nama dari alokasi memori tersebut, supaya program dapat
melacak lokasi memori yang menyimpan data yang diinginkan.
Penamaan variabel pada dasarnya dibebaskan kepada programmer. Nama yang diberikan kepada
variabel disebut identifier. Penamaan identifier variabel pada pemrograman Java mempunyai beberapa
aturan, sebagai berikut :
a.
identifier variabel harus dimulai dengan alfabet huruf besar, huruf kecil, tanda dollar ( $ ) atau
underscore (_). Setelah karakter pertama, dapat diikuti dengan angka;
b.
c.
Kata kunci pada teknologi Java , seperti pada Tabel IV.3, tidak dapat dijadikan nama identifier
variabel.
Tabel IV.3
Kata-kata Kunci pada Teknologi Java yang Tidak Dapat Dijadikan Nama Variabel
abstract
assert
boolean
break
byte
case
catch
char
class
const
continue
default
do
double
else
extends
false
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
null
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
this
throw
throws
transient
true
try
void
volatile
while
39
@2var
b.
_status
c.
tanggal
d.
jumlahBarang
e.
nama_kecil
f.
final_test
g.
int_float
Setelah variabel dideklarasikan dan diberi nama, maka langkah berikutnya adalah melewatkan sebuah
nilai ke variabel tersebut. Nilai yang diberikan kepada sebuah variabel haruslah sesuai dengan tipe data
variabel tersebut. Misalnya untuk nilai berupa karakter harus dilewatkan ke variabel dengan tipe data
char, tidak boleh dilewatkan ke variabel dengan tipe data int. Berikut contoh melewatkan nilai ke
sebuah variabel :
...
public String noPol = D 234 LE;
public int harga = 70000000;
...
Konstanta adalah variabel yang nilainya tidak dapat diubah-ubah. Dalam aplikasi terkadang dibutuhkan
suatu variabel yang dicegah untuk dimodifikasi oleh program lainnya. Hal ini dilakukan untuk menjaga
agar logika program tetap terjaga. Untuk membuat konstanta, digunakan sebuah modifier final,
seperti misalnya pada kelas Mobil pada Contoh 4.2 :
Pada teknologi Java, penyimpanan variabel primitif dan konstanta dilakukan pada Stack Memory.
Panjang memory yang menjadi tempat penyimpanan variabel tergantung dari panjang tipe data dari
variabel. Misalnya untuk menyimpan variabel yang bernilai integer, maka diperlukan 32 bit pada stack
memory.
Pada teknologi Java, ada 2 macam memory yang dipergunakan untuk menyimpan variabel, yaitu Stack
Memory dan Heap Memory. Heap memory digunakan untuk menyimpan variabel referensi, bukan
variabel primitif.
40
MENGGUNAKAN OPERATOR
5 = a;
Operator aritmatika ada yang berupa operator binary (membutuhkan 2 buah operand) dan operator
unary (membutuhkan 1 buah operand). Operator aritmatika yang menggunakan 2 buah operand
(binary) dapat dilihat pada Tabel 5.1.
Tabel 5.1
Operator Aritmatika Binary
Arti
Operator
Operator
Penjumlahan
sum=num1
num2
Pengurangan
diff=num1
num2
Perkalian
prod=num1
num2
Pembagian
quot=num1
num2
Sisa
mod=num1
num2
(modulus)
Contoh
Pemakaian
Keterangan
Operator aritmatika yang membutuhkan 1 buah operator (unary), dapat dilihat pada Tabel 5.2.
41
Tabel 5.2.
Operator Aritmatika Unary
Arti Operator
Operator
Pre-Increment
++operand
Contoh Pemakaian
int i = 8 ;
int j = ++i;
i bernilai 8, j bernilai 8
Post-Increment
operand++
int i = 8;
int j = i++;
i bernilai 9, j bernilai 8
Pre-Decrement
--operand
int i = 8 ;
int j = --i;
i bernilai 7 , j bernilai 7
Post-Increment
operand--
int i=8;
int j = i--;
i bernilai 7, j bernilai 8
Ada konsep mendasar tentang operator post dan pre, seperti yang ditunjukkan pada Contoh 5.1.
Contoh 5.1
1 int a = 10;
2 int b = a++; // nilai b = 10, nilai a = 11
3 int c = ++a; // nilai c = 12, nilai a = 12
Pada post-increment, baris ke-2, nilai awal variabel a di-copy ke variabel b. Kemudian nilai variabel a
ditambah 1, sehingga nilai terakhir b adalah 10, dan nilai terakhir a adalah 11. Kemudian pada preincrement, baris ke-3, nilai variabel a ditambah 1, kemudian hasilnya di-copy ke variabel c, sehingga
nilai terakhir c adalah 12, dan nilai terakhir a juga 12. Urutan proses yang sama juga berlaku pada postdecrement dan pre-decrement.
42
Tabel 5.3.
Operator Bitwise
Arti Operator
Operator
Shift Kiri
<<
Contoh Pemakaian
Keterangan
int b = -16;
int c = b<<2;
nilai c = -64
Shift Kanan,
dengan
pengisian 0
pada bit-bit
sebelah kiri
AND
>>>
int b = -16;
int c = -16>>>2;
nilai c = 1073741820
&
int a = 12;
int b = - 13;
int c = a & b;
nilai c = 0
OR
int a = 12;
int b = -13;
int c = a | b;
nilai c = -1
Exclusive OR
int a = 13;
int b = -13;
int c = a ^ b ;
nilai c = -2
Complement
int a = 12;
int c = ~a;
nilai c = -13
Shift kanan
Contoh 5.2.
int b = -16;
int c = b>>2;
// nilai c = -4
Operator ini akan menggeser bit-bit pada variabel b sebanyak 2 langkah ke kanan, dengan
membuang 2 bit pada lokasi bit dengan nomor indeks paling kecil, dan menambahkan 2 bit dengan
nilai yang sama dengan sign bit pada 2 lokasi bit dengan nomor index paling besar. Visualisasi
proses ini dapat dilihat pada Gambar 5.1.
43
b.
Contoh 5.3.
int b = -16;
int c = -16>>>2;
// nilai c = 1073741820
Operator ini akan menggeser bit-bit pada variabel b sebanyak 2 langkah ke kanan, dengan
membuang 2 bit pada lokasi bit dengan nomor indeks paling kecil, dan menambahkan bit 0 pada 2
lokasi bit dengan nomor bit paling besar. Visualisasi proses ini dapat dilihat pada Gambar 5.2
Gambar 5.2 Shift Kanan dengan Bit Kiri diberi Nilai Bit 0
c.
Shift Kiri
Contoh 5.4.
int b = -16;
int c = b<<2;
// nilai c = -64
Operator ini akan menggeser bit-bit pada variabel b sebanyak 2 langkah ke kiri, dengan membuang
2 bit pada lokasi bit dengan nomor indeks paling besar, dan menambahkan 0 pada 2 lokasi bit
dengan nomor bit paling kecil. Visualisasi proses ini dapat dilihat pada Gambar 5.3.
44
d.
Operator &
Contoh 5.5.
int a =
int b =
int c =
//nilai
12;
- 13;
a & b;
c = 0
Operator ini akan membandingkan nilai bit milik dua variabel dengan nomor indeks yang
bersesuaian menggunakan operator AND ( & ), di mana nilai 1 akan didapatkan jika kedua bit yang
dibandingkan bernilai 1. Visualisasi proses ini dapat dilihat pada Gambar 5.4.
e.
Operator |
Contoh 5.6.
int a = 12;
int b = -13;
int c = a | b;
// nilai c = -1
Operator ini akan membandingkan nilai bit milik dua variabel dengan nomor index yang
bersesuaian menggunakan operator OR (|), di mana nilai 1 akan didapatkan jika salah satu dari
kedua bit yang dibandingkan bernilai 1. Visualisasi proses ini diperlihatkan pada Gambar 5.5.
45
f.
Operator ^
Contoh 5.7.
int a = 13;
int b = -13;
int c = a ^ b ;
// nilai c = -2
Operator ini akan membandingkan nilai bit milik dua variabel dengan nomor index yang
bersesuaian menggunakan operator Exclusive OR (^), dimana nilai 1 akan didapatkan jika nilai
bit kedua variabel berbeda. Visualisasi proses ini diperlihatkan pada Gambar 5.6.
g.
Operator ~
Contoh 5.8.
int a = 12;
int c = ~a;
//nilai c = -13
Operator ini akan melakukan komplemen pada setiap bit dari variabel a, artinya jika bit pada
suatu lokasi bernilai 0, maka nilai bit tersebut diubah menjadi 1, dan jika nilai bit bernilai 1,
maka nilai bit tersebut akan diubah menjadi 0. Visualisasi proses ini dapat dilihat pada
Gambar 5.7.
46
EKSPERIMEN
1.
47
operator yang berada dalam tanda kurung ( ... ) atau disebut juga parantheses;
b.
c.
operator - operator perkalian atau pembagian, yang urutan operasinya dari kiri ke kanan;
d.
operator-operator penjumlahan atau pengurangan, yang urutan operasinya dari kiri ke kanan;
e.
operator bitwise, dengan urutan operasi dari kiri ke kanan, dan dimulai dari operator bitwise paling
kiri diikuti operator di sebelah kanannya dan seterusnya.
Contoh 5.9
int c = 12 * 3 +5 / (8 - 3) ;
c
c
c
c
=
=
=
=
12 * 3 + 5 / 5 ;
36 + 5 / 5;
36 + 1 ;
37;
Contoh 5.10.
int c = 3 + 4 >> 1 + 1 << 1;
c
c
c
c
=
=
=
=
7 >> 1 + 1 << 1;
7 >> 2 << 1;
1 << 1;
2;
EKSPERIMEN
Analisa hasil operasi aritmatika berikut ini dan buktikan jawaban Anda
dengan membuat program :
a.
x = (2 + 12) / 7 - 2
b.
c.
x = 3.0 <<1
48
Jika terjadi assigning nilai dari tipe data dengan representasi bit yang lebih kecil ke tipe data
dengan representasi bit yang lebih besar, seperti yang diperlihatkan pada contoh berikut ini:
Contoh 5.11.
short a = 12;
int b = a ;
b.
Jika terjadi assigning nilai dari tipe data integral ke tipe data floating-point, seperti yang
diperlihatkan pada Contoh 5.12.
Contoh 5.12.
int a = 30;
float b = a ;
Tipe casting merupakan proses pengubahan representasi bit variabel primitif dari representasi bit yang
lebih tinggi ke representasi bit yang lebih rendah. Sintak dari type casting adalah sebagai berikut :
identifier = (target_type) value ;
dengan keterangan :
a.
b.
target_type = tipe data yang diinginkan menjadi tipe data dari value;
c.
Contoh 5.13.
int num1 = 34;
int num2 = 45;
short num3 = (short)(num1 + num2 );
System.out.println(num3);
Penjumlahan variabel num1 dan num2 akan menghasilkan nilai integer. Nilai integer ini tidak dapat diassign di variabel num3 yang bertipe data short. Setelah dikompilasi dan dieksekusi, maka program
akan menghasilkan output yaitu 79. Contoh berikut ini menunjukkan apabila pada Contoh 5.13 tidak
dilakukan casting.
Contoh 5.14.
int num1 = 34;
int num2 = 45;
short num3 = (num1 + num2 );
System.out.println(num3);
49
ketika program dikompilasi, kompilasi akan gagal, dan compiler akan memberikan pesan error :
Tipe casting, sebenarnya adalah proses pemotongan / chopping bit. Bit yang dipotong adalah bit-bit
dengan nomor indeks paling besar. Bit-bit tersebut dipotong sehingga didapatkan representasi bit yang
diinginkan. Visualisasi type casting diperlihatkan pada Gambar 5.8.
Pada Gambar 5.8 diperlihatkan representasi angka 36 yang bertipe data long (64 bit). Representasi ini
akan dibuat menjadi representasi int ( 32 bit ). Cara melakukan casting adalah dengan memotong bit
ke-32 sampai ke-63 dari representasi long, sehingga hanya tersisa bit ke-0 sampai ke-31. Meskipun
demikian, karena nilainya masih di dalam batas integer, maka nilainya tetap 36.
contoh berikut memperlihatkan suatu variabel bertipe-data long yang nilainya berada di luar batas tipe
data int. Variabel long ini akan di-casting ke int.
Contoh 5.15.
int num1;
long num2 = 123987654321L;
num1 = (int)(num2);
System.out.println(num1);
Ketika program dikompilasi dan dieksekusi, maka program akan mengeluarkan output -566397263. Nilai
variabel num1 yang berbeda dari num2 disebabkan oleh dipotongnya bit ke-32 sampai ke-63 dari
variabel num2.
50
EKSPERIMEN
1.
Analisa program berikut ini. Buktikan hasil analisa Anda dengan keluaran
yang dihasilkan :
a.
float x = (float)(int)(double)(short)3;
b.
float x = (double)(int)(double)(short)3;
c.
int y = (int)4.5;
d.
short b = (byte)128<<1;
byte bt = 135;
b.
byte bt = (byte)135;
Apabila terdapat operasi aritmatika yang hasilnya melewati batas limit tipe data, dan hasilnya disimpan
ke variabel dengan tipe data yang batas nilainya di bawah hasil operasi aritmatika tersebut, maka ketika
dilakukan kompilasi dan eksekusi, maka hasil operasi aritmatika tersebut adalah negatif. Perhatikan
Contoh 5.16.
Contoh 5.16.
int a = 55555;
int b = 66666;
int c = a * b;
System.out.println(c);
Setelah dikompilasi dan dieksekusi, maka program akan menghasilkan: -591337666. Hasil ini tidak
sesuai dengan yang diinginkan, yaitu 3703629630.
Jika operasi aritmatika yang akan dibuat memiliki kemungkinan menghasilkan nilai di luar batas nilai
tipe data, maka sebaiknya pada salah satu operand, tipe datanya dimodifikasi menjadi tipe data
dengan representasi bit yang lebih tinggi, sehingga nilai yang akan dihasilkan masih berada di dalam
rentang nilai tipe data, dan variabel penyimpan hasil akhirnya juga dimodifikasi ber-tipe data dengan
representasi bit yang lebih tinggi. Perhatikan Contoh 5.17.
Contoh 5.17
int a = 55555;
long b = 66666;
long c = a * b;
System.out.println(c);
Setelah dikompilasi dan dieksekusi, maka program akan menghasilkan 3703629630. Jadi, memodifikasi
tipe data operand b menjadi long, maka operasi aritmatika akan menghasilkan nilai bertipe long.
Variabel penyimpan data, yaitu c dengan demikian juga harus dimodifikasi menjadi long.
51
Compiler mempunyai asumsi dasar tentang tipe data integral dan floating-point. Untuk tipe data
integral, asumsi-asumsi dasar compiler adalah sebagai berikut :
a.
Nilai yang di-assign tanpa penambahan keterangan apapun, diasumsikan sebagai nilai integer.
Perhatikan Contoh 5.18.
Contoh 5.18
int a = 12345;
long b = 3456;
short c = 12367;
Pada Contoh di atas, nilai-nilai yang di-assign ke setiap variabel a, b, dan c diasumsikan sebagai
integer. Pada baris ke-1, nilai 12345 adalah integer, kemudia nilai tersebut di-assign ke variabel a.
Begitu juga dengan baris ke-2, nilai 3456 diasumsikan sebagai integer. Nilai integer tersebut diassign ke variabel b yang bertipe data long. Pada baris ke-3, nilai 12367 diasumsikan sebagai
integer. Nilai integer tersebut di-assign ke variabel c yang bertipe data short. Meskipun nilai integer
akan dipotong menjadi 16 bit, tetapi karena nilai 12367 masih berada di dalam batas nilai short,
maka kompilasi program akan sukses.
Jika ingin keluar dari asumsi, untuk nilai long, penulisannya diakhiri dengan huruf L atau l.
Perhatikan Contoh 5.19.
Contoh 5.19
long
b = 3456L;
Jika ingin keluar dari asumsi, untuk nilai short dan byte, maka dilakukan type-casting. Perhatikan
Contoh 5.20.
Contoh 5.20.
short c = (short)12367;
byte d = (byte)12;
b.
Jika pada suatu operasi aritmatika, operand-operand pada ruas kanan berbeda tipe datanya (
semuanya masih termasuk tipe data integral ), dan semua tipe data merupakan tipe data yang
representasi bitnya di bawah integer, maka hasil operasi aritmatika tersebut akan diasumsikan
sebagai integer. Perhatikan Contoh 5.21.
Contoh 5.21.
byte theByte = (byte)127 + (short)12346;
Jika program ini dikompilasi, maka akan kompilasi akan gagal, dan kompiler akan mengeluarkan
pesan error:
Test.java:24: possible loss of precision
found
: int
required: byte
byte theByte = (byte)127 + (short)12346;
^
1 error
52
Perhatikan bahwa compiler menemukan nilai int sebagai hasil dari operasi penjumlahan. Ini berarti,
hasil penjumlahan tidak dianggap sebagai short, tetapi sebagai int.
c.
Jika pada suatu operasi aritmatika, operand-operand pada ruas kanan berbeda tipe datanya (
semuanya masih termasuk tipe data integral ), dan salah satu tipe data merupakan tipe data yang
representasi bitnya di atas integer, yaitu long, maka hasil operasi aritmatika tersebut akan
diasumsikan sebagai long. Perhatikan Contoh 5.22.
Contoh 5.22.
byte theByte = (byte)127 + (long)12346;
Jika program ini dikompilasi, maka akan kompilasi akan gagal, dan kompiler akan mengeluarkan
pesan error:
Test.java:24: possible loss of precision
found
: long
required: byte
byte theByte = (byte)127 + (long)12346;
^
1 error
Perhatikan bahwa kompiler menemukan nilai long sebagai hasil dari operasi penjumlahan. Ini
berarti, hasil penjumlahan tidak dianggap sebagai int, tetapi sebagai long.
Untuk tipe data floating-point, kompiler memiliki asumsi-asumsi sebagai berikut :
a.
Nilai yang di-assign tanpa penambahan keterangan apapun akan diasumsikan sebagai double.
Perhatikan contoh 5.23.
Contoh 5.23.
double variable = 34.5;
Jika diinginkan nilai bilangan real tidak direpresentasikan dalam double ( atau ingin
direpresentasikan dalam float ), maka penulisan nilainya diakhiri dengan huruf F atau f.
Perhatikan Contoh 5.24.
Contoh 5.24.
float variable1 = 34.5F;
float variable2 = 3.67f;
b.
Jika pada operasi aritmatika dengan semua operand pada ruas kanan menggunakan tipe data
floating-point, maka hasil operasi aritmatika tersebut direpresentasikan dengan tipe data yang
mengikuti tipe data dengan representasi tertinggi pada ruas kanan operasi aritmatika tersebut.
Perhatikan Contoh 5.25.
Contoh 5.25.
float variable1 = 35.7F + 3.0 ;
53
Contoh 5.25 menggambarkan operasi aritmatika, dengan operand pertama bertipe data float, dan
operand kedua bertipe data double. Hasil operasi aritmatika tersebut disimpan pada variable1. Jika
program dikompilasi, maka compiler akan mengeluarkan pesan error sebagai berikut :
Jika pada operasi aritmatika dengan sebagian operand pada ruas kanan menggunakan tipe data
floating-point dan sebagian menggunakan tipe data integral, maka hasil operasi aritmatika tersebut
direpresentasikan dengan tipe data floating-point yang mengikuti tipe data floating-point dengan
representasi bit tertinggi pada ruas kanan operasi aritmatika tersebut. Perhatikan Contoh 5.26.
Contoh 5.26.
float variable2 = 35 + 3.0 ;
Contoh 5.26 menggambarkan operasi aritmatika, dengan operand pertama bertipe data integer,
dan operand kedua bertipe data double. Hasil operasi aritmatika tersebut disimpan pada variable2.
Jika program dikompilasi, maka compiler akan mengeluarkan pesan error sebagai berikut :
Pada Contoh 5.26, compiler menganggap hasil penjumlahan merupakan nilai yang bertipe double,
karena salah satu operand-nya adalah floating-point dan bertipe-data double. Dari pesan error ini
terlihat bahwa untuk operasi aritmatika dengan salah satu operand-nya bertipe double dan
operand lainnya bertipe integer, maka hasil operasi tersebut akan bertipe double.
EKSPERIMEN
Analisa program berikut ini. Buktikan hasil analisa Anda dengan keluaran yang
dihasilkan :
54
a.
b.
Obyek pada dasarnya sama seperti variabel, yang merupakan elemen penyimpanan data, hanya saja
ketika mendeklarasikan sebuah obyek, yang dialokasikan pada Stack Memory adalah memory yang
tidak akan diisi dengan nilai yang sebenarnya, tetapi diisi dengan alamat memory lain yang berada pada
heap memory, dengan kata lain memory yang dialokasikan untuk sebuah obyek akan mereferensi
merujuk ke memory lain pada heap memory. Alokasi memory pada heap memory adalah alokasi
memory untuk menyimpan obyek. Variabel yang menunjuk ke obyek pada heap memory disebut
variabel referensi obyek.
Bayangkanlah variabel referensi obyek seperti sebuah surat yang dialamatkan ke sebuah rumah. Alamat
yang tertera pada surat sebenarnya menunjuk kepada rumah tertentu. Obyeknya sendiri adalah rumah
dengan alamat yang sama dengan alamat yang tertera pada surat. Gambar 6.1 mengilustrasikan surat
yang menunjuk ke rumah yang alamatnya tertera pada surat tersebut.
Gambar 6.1 memperlihatkan ada 2 buah surat yang akan dikirim ke 2 rumah yang masing-masing
memiliki alamat yang berbeda. Surat dapat dikatakan sebagai perwakilan dari rumah. Rumah yang
diwakilinya dapat diidentifikasi dari alamat rumah yang tertera pada surat.
Secara teknis, variabel referensi obyek ditempatkan pada Stack Memory. Variabel ini menunjuk ke
obyek yang berada pada heap memory. Ilustrasinya dapat dilihat pada Gambar 6.2.
Obyek pada dasarnya adalah kumpulan variabel. Variabel-variabel di dalam sebuah obyek dapat
berupa variabel primitif maupun variabel referensi obyek. Komposisi variabel di dalam obyek mengikuti
komposisi class yang menjadi acuan bangunan obyek tersebut.
55
ClassName merepresentasikan nama kelas atau tipe dari obyek yang direferensi oleh referensi
obyek.
b.
Contoh 6.1 memperlihatkan kelas Rumah yang menyimpan data berupa luasTanah, luasBanguan,
dan harga. Contoh 6.1 juga memperlihatkan kelas AplikasiMakelarRumah yang tidak terdiri atas
variabel. Pada class AplikasiMakelarRumah didefinisikan method yang bernama main(), yang
merupakan method utama dalam program yang memuat alur program utama.
Contoh 6.1.
//File : Rumah.java
public class Rumah{
public int luasTanah = 100;
public int luasBangunan;
public int harga;
public cetakInfoRumah( ){
System.out.println(Luas Tanah = + luasTanah);
System.out.println(Harga = + harga);
}
}
//File : AplikasiMakelarRumah.java
public class AplikasiMakelarRumah{
public static void main(String [] args ){
Rumah rumah1;
Rumah rumah2;
}
}
Pada kelas AplikasiMakelarRumah, baris ke-4 adalah deklarasi variabel referensi obyek yang
diberi nama rumah1. Baris ke-5 adalah deklarasi variabel referensi obyek yang diberi nama rumah2.
Kedua variabel tersebut belum menunjuk ke satu obyek pun pada heap memory.
56
Catatan : untuk sementara, sintak untuk menginisialisasi obyek adalah seperti yang telah ditunjukkan.
Pada bab-bab berikut akan dibahas mengenai cara instantiasi obyek yang lebih kompleks.
Contoh 6.2 berikut ini memperlihatkan kelas AplikasiMakelarRumah dari Contoh 6.1 yang
dimodifikasi. Pada baris ke-6, sebuah obyek Rumah yang direferensi oleh rumah1 diinstantiasi, dan
pada baris ke-7, sebuah obyek Rumah yang direferensi oleh rumah2 diinstantiasi.
Contoh 6.2.
//File : AplikasiMakelarRumah.java
public class AplikasiMakelarRumah{
public static void main(String [] args ){
Rumah rumah1;
Rumah rumah2;
rumah1 = new Rumah( );
rumah2 = new Rumah( );
}
}
Pada kelas Rumah, nilai luasTanah ditetapkan = 100, sedangkan luasBangunan dan harga tidak
diberi nilai awal. Ini berarti ketika sebuah obyek Rumah diinstantiasi, nilai awal luasTanah-nya = 100,
luasBangunan = 0, dan harga = 0. Hasil dari instantiasi pada Contoh 6.2 dapat divisualisasikan
pada Gambar 6.3.
Gambar 6.3 memperlihatkan bahwa variabel referensi obyek rumah1 dan rumah2 berada pada stack
memory dan menyimpan nilai berupa alamat memori yang ditempati oleh obyek Rumah yang
bersesuaian. Nilai awal masing-masing variabel pada setiap obyek sama : luasTanah = 100,
luasBangunan = 0, harga = 0.
EKSPERIMEN
Ubahlah nilai luasBangunan pada class Rumah pada Contoh 6.1. menjadi 120. Lalu
tambahkan baris program untuk menampilkan nilai variabel atribut milik rumah1 dan
rumah2. Kompilasilah, lalu jalankan program AplikasiMakelarRumah.Perhatikanlah nilai
luasBangunan setiap obyek Rumah ! Apakah perubahan yang terjadi dibandingkan
keluaran / output pada Contoh 6.2 ? Mengapa demikian ?
57
object_name adalah nama obyek yang variabel anggota/atributnya akan diakses dimanipulasi.
identifier adalah nama variabel milik object_name yang akan diakses/dimanipulasi.
value adalah nilai yang akan disimpan ke variabel.
Contoh 6.3
//File : AplikasiMakelarRumah.java
public class AplikasiMakelarRumah{
public static void main(String [] args ){
Rumah rumah1;
Rumah rumah2;
rumah1 = new Rumah( );
rumah2 = new Rumah( );
rumah1.luasTanah = 120;
rumah2.luasBangunan = 80;
rumah1. harga = 200000000;
}
}
Visualisasi hasil akhir program pada memory ditunjukkan pada Gambar 6.4.
EKSPERIMEN
1.
2. Buatlah baris-baris program untuk menampilkan semua data pada rumah1 dan rumah2.
58
6.8 Memindahkan Sebuah Referensi dari Satu Obyek ke Obyek yang Lain
Sebuah variabel referensi obyek tidak selalu terpaku merujuk/mereferensi suatu obyek tertentu.
Variabel ini dapat saja mereferensi obyek lain. Seperti diperlihatkan pada baris ke-8 pada Contoh 6.4,
pernyataan :
rumah1 = rumah2;
menyatakan bahwa variabel rumah1 diisi dengan isi variabel rumah2. Dengan demikian variabel
referensi rumah1 tidak lagi merujuk ke obyek semula, tetapi merujuk obyek yang ditunjuk oleh
variabel rumah2.
Contoh 6.4.
//File : AplikasiMakelarRumah.java
public class AplikasiMakelarRumah{
public static void main(String [] args ){
Rumah rumah1;
Rumah rumah2;
rumah1 = new Rumah( );
rumah2 = new Rumah( );
rumah1 = rumah2;
rumah1.luasTanah = 120;
rumah2.luasBangunan = 80;
rumah1. harga = 200000000;
}
}
Hasil akhir program tersebut dapat dilihat pada Gambar 6.5 berikut ini :
EKSPERIMEN
Tambahkan baris program pada main method pada Contoh 6.4, setelah baris ke-11 sebagai berikut :
System.out.println(rumah1==rumah2);
Perhatikan output yang dihasilkan program ! Jika outputnya adalah false, variabel referensi rumah1
menunjuk obyek yang berbeda dengan obyek yang ditunjuk oleh variabel referensi rumah2. Jika
outputnya adalah true, maka variabel referensi rumah1 menunjuk obyek yang sama dengan obyek
yang ditunjuk oleh variabel referensi rumah2.
59
60
b.
String dapat diinstantiasi tanpa menggunakan kata kunci new, berbeda dengan obyek lain yang
harus diinstantiasi dengan menggunakan kata kunci new.
Contoh pendeklarasian dan inisialisasi variabel String dapat dilihat pada Contoh 7.1.
Contoh 7.1
//File : AplikasiSiswa.java
public class AplikasiSiswa{
public static void main (String[] args){
String namaSiswa1 = Adi;
String namaSiswa2 = new String (Adi);
String namaSiswa3 = Adi;
String namaSiswa4 = new String(Adi);
System.out.println(namaSiswa1 == namaSiswa2);
System.out.println(namaSiswa1 == namaSiswa3);
System.out.println(namaSiswa1.equals(namaSiswa2));
System.out.println(namaSiswa2 == namaSiswa4);
System.out.println(namaSiswa2.equals(namaSiswa4));
}
}
Ada perbedaan pada representasi memory antara instanstiasi obyek String menggunakan new
dengan obyek lainnya. Pada instanstiasi obyek lain, akan dibentuk 1 obyek pada heap memory yang
memuat variabel-variabel atribut / anggota.
Instanstiasi obyek String menggunakan new akan membentuk 2 buah obyek, yaitu :
a.
obyek String, yang memuat referensi ke suatu String literal pada literal pool.
b.
String literal, yang memuat karakter-karakter. String literal ini terletak pada literal pool.
61
Catatan : Literal Pool adalah satu blok alokasi memory pada heap memory yang khusus berisi kumpulan
String literal. Alokasi literal pool ini dimaksudkan untuk mengakomodasi apabila terdapat lebih dari satu
obyek String yang mereferensi ke literal yang sama, tidak perlu membuat 2 string literal dengan
komposisi karakter yang sama, tetapi cukup hanya 1 string literal saja.
Pada baris ke-6, obyek namaSiswa2 diinstanstiasi dengan representasi karakter = Adi. Pada proses
instanstiasi ini, JVM akan membentuk obyek String dan String Literal pada literal pool. Isi literal pool ini
adalah representasi karakter dari namaSiswa2, yaitu Adi. Obyek String bernilai alamat string literal
tersebut.
Kemudian obyek namaSiswa4 diinstanstiasi dengan representasi karakter = Adi. Pada proses
instanstiasi ini, JVM akan membentuk obyek String dan String Literal pada literal pool. Isi literal pool ini
adalah representasi karakter dari namaSiswa4, yaitu Adi. Obyek String bernilai alamat string literal
tersebut.
Meskipun representasi karakternya sama-sama Adi, tetapi String literal untuk namaSiswa2 tidak
sama dengan String literal, se namaSiswa4 shingga ketika baris ke-12 dieksekusi, maka akan
menghasilkan nilai false.
Jika kita ingin membandingkan namaSiswa2 dan namaSiswa4 dengan logika : jika nama kedua
siswa itu sama, berarti kedua siswa tersebut sebenarnya adalah siswa yang sama , maka kita harus
menggunakan method equals() seperti pada baris ke-13.
62
7.8 Penggunaan Operator == dan Method equals ( ) untuk Membandingkan Dua Buah String
Untuk membandingkan dua buah obyek String, dapat dilakukan dengan menggunakan operator ==
atau method equals().
Operator == lebih menekankan apakah kedua obyek String tersebut menunjuk ke string literal yang
sama. Jika kita perhatikan Gambar 7.1, maka jika baris ke-9 Contoh 7.1 dieksekusi, maka akan
menghasilkan nilai false, karena string literal namaSiswa1 dan namaSiswa2 tidak sama ( meskipun
representasi karakternya sama ).
Sedangkan method equals() lebih menekankan apakah representasi karakter kedua String sama
atau tidak. Jika kita perhatikan Gambar 7.1, maka jika baris ke-11 dieksekusi, maka hasilnya akan
menjadi true, meskipun string literal namaSiswa1 dan namaSiswa2 tidak sama.
Contoh 7.2
//File : Person.java
public class Person{
public static void main (String[] args){
String nama = Surya;
String kota = Bandung;
System.out.println(Nama saya + nama +
, tinggal di + kota);
}
}
EKSPERIMEN
Apakah ekspresi String berikut ini valid (benar, dapat dikompilasi) ?
a. String jumlah = new String (jumlah = + 200 ) ;
b. String nama = Rano + Karno;
c. String word = Hello ; word += World ;
63
Spesifikasi Pustaka kelas-kelas Java adalah dokumen yang menerangkan kegunaan kelas-kelas pada API
Java. Spesifikasi ini dibuat berdasarkan versi SDK-nya. Misalnya, SDK1.3 mempunyai spesifikasi pustaka
sendiri, SDK1.4 mempunyai pustaka sendiri, dan seterusnya. Gambar 7.2 memperlihatkan tampilan
Spesifikasi Pustaka Class Java.
Pada pustaka Java terdapat 2 bagian utama, yaitu daftar kelas dan halaman keterangan kelas. Pada
Daftar kelas, terdapat keterangan tentang kelas yang diseleksi, melingkupi keterangan tentang field
(variabel publik statik), dan method.
Spesifikasi Pustaka kelas Java dapat digunakan untuk mempelajari method. Sebagai contoh, untuk
mempelajari method yang sudah kita gunakan :
System.out.println (Test);
Gunakan web browser untuk masuk ke halaman utama dari dokumentasi J2SE API.
b.
Pada bagian daftar kelas, cari nama kelas System, lalu kliklah. Maka pada halaman Keterangan
kelas akan muncul keterangan tentang kelas System. Jika sudah terbiasa dengan konvensi
penamaan kelas, maka pemanggilan method yang didahului dengan identifier yang diawali dengan
huruf besar, besar kemungkinan identifier itu adalah nama kelas. System merupakan nama kelas.
Oleh karena itu langkah pertama adalah mencari nama kelas System.
c.
Pada bagian Keterangan kelas, cari pada bagian Field, nama variabel out. Lihat Gambar 7.3.
d.
Perhatikan bahwa variabel out merupakan variabel statik yang berasal dari kelas PrintStream.
Oleh karena itu, kliklah PrintStream. Maka akan muncul halaman keterangan kelas
PrintStream.
e.
Pada halaman keterangan kelas PrintStream, carilah method println() pada daftar
method.
f.
Pada daftar method, terdapat banyak method println(). Method println yang kita cari
adalah method println() yang memiliki argumen String, yaitu println(String s).
64
Dalam banyak kasus pemrograman Java, muncul kebutuhan-kebutuhan untuk mengevaluasi suatu
variabel. Evaluasi variabel dibutuhkan untuk memutuskan arah aliran program. Untuk melakukan
evaluasi terhadap satu / lebih variabel, digunakan operator relasional yang akan membandingkan
variabel-variabel yang akan dievaluasi dengan nilai-nilai tertentu. Sedangkan operator kondisional
merupakan operator-operator yang mengatur arah aliran program berdasarkan hasil evaluasi terhadap
satu / beberapa variabel.
Operator
Is equal to
Example
==
int i = 1;
System.out.println(i==1);
// (output : true)
!=
int i = 1;
System.out.println(i!=1);
// (output : false)
Is less than
<
<=
Is greater than
>
int i = 1;
System.out.println(i<1); // (output : false)
int i = 1;
System.out.println(i<=1); //(output : true)
int i = 1;
System.out.println(i>1); //(output : false)
>=
int i = 1;
System.out.println(i>=1);
// (output : true)
65
Tabel 8.2
Operator Kondisional
Condition
Operator
Example
&&
int i = 1;
int j = 2;
System.out.println((i<1)&&(j>0));
// (output : false)
If either condition OR
another condition
||
int i = 1;
int j = 2;
System.out.println((i<1)||(j>0));
// (output : true)
NOT
int i = 1;
System.out.println(!(i<3));
// (output : false)
8.4.1 Konstruksi if
Konstruksi if merupakan bentuk konstruksi pengambilan keputusan dengan 2 kemungkinan
keputusan. Kemungkinan-kemungkinan keputusan itu akan dipilih berdasarkan suatu kondisi yang
diperiksa. Kondisi tersebut merupakan suatu ekspresi boolean / boolean expression.
Sintak dasar dari konstruksi if adalah sebagai berikut :
if ( boolean_expression ){
code block;
} //akhir dari konstruksi if
//program dilanjutkan
dengan keterangan :
a.
b.
66
Jika boolean_expression bernilai benar, maka baris-baris program yang berada dalam code_block akan
dieksekusi. Setelah code_block dieksekusi, maka baris-baris program yang akan dijalankan adalah
program di luar konstruksi if. Jika boolean_expression bernilai salah, maka baris-baris program yang
berada dalam code_block tidak dieksekusi, dan program berikutnya yang dijalankan adalah program di
luar konstruksi if.
Proses pengambilan keputusan dengan menggunakan konstruksi if dapat divisualisasikan
menggunakan diagram alir, seperti pada Gambar 8.1. Berikut ini contoh pengambilan keputusan.
Contoh 8.1
//File : HasilUjian.java
public class HasilUjian{
public static void main(String[] args){
int nilai1 = 8;
int nilai2 = 7;
int nilai3 = 5;
float rata_rata = (float)(nilai1 + nilai2 + nilai3)/3;
if(rata_rata<5){
System.out.println(Tidak Lulus);
}
System.out.println(Nilai Rata-rata = +rata_rata);
}
}
Contoh 8.1 adalah program pengambilan keputusan apakah seorang siswa lulus atau tidak lulus.
Keputusan tersebut diambil berdasarkan nilai rata-rata yang diambil dari hasil-hasil ujian : nilai1,
nilai2, dan nilai3. Rumus nilai rata-rata dinyatakan pada baris ke-7.
Proses evaluasi nilai rata-rata menggunakan if diperlihatkan pada baris ke-8, dengan
boolean_expression-nya adalah :
rata-rata < 5
Pada Contoh 8.1 nilai rata-rata adalah 6,6666665, sehingga boolean_expression rata-rata < 5 akan
bernilai false, sehingga, code_block pada baris ke-9 tidak dieksekusi. Eksekusi program berikutnya
adalah eksekusi baris ke-11. Hasil keluaran dari program Contoh 8.1 adalah :
Nilai Rata-rata = 6.6666665
67
EKSPERIMEN
1.
Gantilah nilai pada nilai1 menjadi 2. Catatlah keluaran / output yang dihasilkan.
2.
Ubahlah syarat ketidaklulusan : seseorang akan dinyatakan tidak lulus jika nilai rataratanya < 5 DAN salah satu di antara nilai1, nilai2,nilai3 ada yang bernilai <5.
if ( boolean_expression_1 ){
code block 1;
} else if ( boolean_expression_2 ){
code block 2;
}
.
.
.
else{
code block n;
}
keterangan :
a.
b.
68
Contoh 8.2
//File : HasilUjian.java
public class HasilUjian{
public static void main(String[] args){
int nilai1 = 8;
int nilai2 = 7;
int nilai3 = 5;
float rata_rata = (float)(nilai1 + nilai2 + nilai3)/3;
if(rata_rata<5){
System.out.println(Tidak Lulus);
} else if ((rata_rata>=5) && (rata_rata<6)){
System.out.println(Harus ikut ujian perbaikan);
} else { // rata_rata >= 6
System.out.println(Lulus);
}
System.out.println(Nilai Rata-rata = + rata_rata);
}
}
rata-rata < 5
rata-rata 5 DAN rata-rata < 6
kondisi di luar a. dan b. , yaitu rata-rata
Pada baris ke-7, nilai rata-rata yang disimpan pada variabel rata-rata adalah 6,6666665. Nilai variabel
rata_rata ini akan dievaluasi pada baris-baris berikutnya untuk menentukan pesan apa yang akan
ditampilkan di layar monitor.
Pertama-tama variabel rata_rata dievaluasi pada baris ke-8, dengan boolean_expression sebagai
berikut :
rata_rata < 5
Hasil evaluasinya akan bernilai false, karena jelas bahwa seharusnya 6,6666665 lebih besar daripada 5,
dan bukan lebih kecil. Karena hasil evaluasi bernilai false, maka code block pada baris ke-9 tidak
dieksekusi.
Kemudian dilakukan evaluasi untuk kondisi kedua, yang dinyatakan dengan boolean_expression pada
baris ke 10 :
Pada evaluasi kedua, terdapat boolean_expression yang merupakan ekspresi kondisional, yang
membandingkan dua kondisi dalam operator && ( AND / dan ), di mana nilai dari ekspresi akan benar
jika dan hanya jika kedua kondisi yang dibandingkan juga bernilai benar.
Kondisi pertama : rata_rata>=5, akan menghasilkan nilai true, karena 6,6666665 memang lebih
besar daripada 5. Pada kondisi kedua : rata_rata < 6, akan menghasilkan nilai false, karena
6,6666665 seharusnya lebih besar daripada 6, bukan lebih kecil daripada 6. Karena kondisi pertama
bernilai true dan kondisi kedua bernilai false, maka boolean_expression menjadi :
69
Dengan demikian, hasil boolean_expression adalah false. Berarti hasil evaluasi juga bernilai false.
Karena hasil evaluasi bernilai false, maka code block pada baris ke-11 tidak dieksekusi.
Selanjutnya evaluasi akan berlanjut ke blok else berikutnya, pada baris ke-12. Pada baris ini tidak
disebutkan kondisi yang akan diuji :
else{
Hal ini berarti, kondisi yang diuji adalah kondisi di luar semua kondisi yang telah diuji. Kondisi yang telah
diuji adalah rata_rata < 5, (rata_rata>=5)&&(rata_rata<6). Kondisi di luar itu tentu
saja adalah :
rata_rata >=6
Karena nilai rata_rata adalah 6,6666665, maka pernyataan rata_rata >= 6 akan menghasilkan nilai true.
Karena hasil evaluasi menghasilkan nilai true, maka code block pada baris ke-13 akan dieksekusi :
System.out.println(Lulus);
Setelah baris ke-13 dieksekusi, maka eksekusi program berikutnya adalah baris ke-15 :
System.out.println(Nilai rata-rata = + rata_rata);
Program pada Contoh 8.2 akan menghasilkan output berikut :
Lulus Nilai Rata-rata = 6.6666665
EKSPERIMEN
8.3.5
3.
Gantilah nilai pada nilai2 pada Contoh 8.2 menjadi 0. Catatlah keluaran / output yang
dihasilkan.
4.
Konstruksi Switch
Konstruksi switch adalah konstruksi pengambilan keputusan yang mengevaluasi kemungkinankemungkinan nilai dari variabel yang dievaluasi. Bentuk umum syntax konstruksi switch adalah sebagai
berikut:
switch( variabel ) {
case nilai_literal_1 :
code_block_1;
break;
case nilai_literal_2 :
code_block_2;
break;
.
.
default:
code_block_default;
break;
}
70
keterangan :
a.
b.
variabel adalah variabel yang nilainya akan dievaluasi. variabel hanya dapat bertipe-data char,
byte, short, atau int;
c.
case adalah kata kunci yang mengindikasikan sebuah nilai yang diuji. Kombinasi kata kunci case
dan nilai_literal disebut case label;
d.
nilai_literal_k adalah nilai yang mungkin akan menjadi nilai variabel. nilai_literal_k tidak dapat
berupa variabel, ekspresi, atau method, tetapi dapat merupakan konstanta. k = {default, 1,2,...,n };
e.
break adalah pernyataan yang sifatnya opsional, yang mengakibatkan aliran program keluar dari
blok switch. Jika setelah code_block_k tidak terdapat pernyataan break, maka aliran program
akan masuk ke case berikutnya. k = {default, 1,2,3,...,n};
f.
default adalah kata kunci yang mengindikasikan code_block_default akan dieksekusi jika semua
case yang diuji tidak sesuai dengan nilai variabel .
Contoh 8.3
//File : HasilUjian.java
public class HasilUjian{
public static void main(String[] args){
int nilai1 = 8;
int nilai2 = 7;
int nilai3 = 5;
float rata_rata = (float)(nilai1 + nilai2 + nilai3)/3;
switch((int)rata_rata){
case 0 :
case 1 :
case 2 :
case 3 :
case 4 :
System.out.println(Tidak Lulus);
break;
case 5 :
System.out.println(Ikut ujian perbaikan);
break;
default :
System.out.println(Lulus);
break;
}
System.out.println(Nilai Rata-rata = + rata_rata);
}
}
71
Pada Contoh 8.3, setelah nilai variabel rata_rata dikalkulasi, dilakukan evaluasi terhadap
rata_rata :
switch((int)rata_rata){
Pada baris 9, variabel rata_rata dievaluasi nilainya, dan dibandingkan dengan kemungkinankemungkinan nilai. Kemungkinan-kemungkinan nilai tersebut adalah 1, 2, 3, 4, 5 dan selebihnya ( 6,7,8,
dst ). Nilai variabel rata_rata pada baris ke-7 adalah 6,6666665. Nilai variabel rata_rata ini sebelum
diuji pada baris ke-9 di-casting ke tipe data int, sehingga nilanya menjadi 6 (sisa desimalnya
dihilangkan).
Pengujian dilakukan dengan pertama-tama membandingkan nilai rata_rata ter-casting dengan nilai
pada case yang pertama, yaitu nilai literal 0. Karena nilai literal pada case pertama tidak sama
dengan nilai rata_rata ter-casting, maka evaluasi dilanjutkan ke case berikutnya. Hal yang sama
terjadi juga pada case kedua. Karena pada case pertama ( 0 ) sampai case keenam (5 ) tidak
didapatkan hasil true, maka pemeriksaan dilanjutkan ke nilai di luar { 0,1,...,5 }, yaitu default.
Pada pengujian default, evaluasi menghasilkan nilai true, karena nilai rata_rata ter-casting
berada di luar { 0, 1, 2,..., 5 }. Karena menghasilkan nilai true, maka code block yang dijalankan adalah
yang dilingkupi oleh blok default. Proses akan keluar dari block switch setelah mengeksekusi
pernyataan break pada baris 24.
EKSPERIMEN
5.
Gantilah nilai pada nilai 1 dan nilai 2 pada Contoh 8.3 menjadi 0. Kemudian
modifikasilah baris berikut :
case 1
6.
case 1
72
MENGGUNAKAN
KONSTRUKSI PENGULANGAN (LOOPING)
Konstruksi pengulangan adalah konstruksi yang digunakan untuk mengakomodasi pengulangan proses.
Konstruksi pengulangan diperlukan untuk lebih mengefisienkan penulisan kode program, sehingga tidak
perlu dilakukan pengulangan penulisan kode untuk merepresentasikan suatu proses yang berulang.
Ada beberapa konstruksi pengulangan yang digunakan dalam bahasa pemrograman Java, antara lain :
a.
b.
c.
Konstruksi while
Konstruksi for
Konstruksi do/while
while(boolean_expression){
code_block;
} //akhir dari konstruksi while
Pada konstruksi while, langkah-langkah proses perulangannya adalah sebagai berikut :
a.
b.
Jika nilai boolean_expression adalah true, maka code_block akan dieksekusi. Jika tidak, maka
code_block tidak dieksekusi.
c.
Jika di dalam code_block terdapat pernyataan kondisi yang menyebabkan proses harus keluar dari
blok while, maka proses akan keluar dari pengulangan, meskipun boolean_expression masih
bernilai true.
Pada Contoh 9.1 diperlihatkan contoh penggunaan konstruksi while. Pada baris ke-3 sampai ke-5,
dideklarasikan 3 buah variabel num1, num2, dan num3. Variabel num1 diberi nilai 0, num2 diberi nilai
23, dan num3 diberi nilai yang merupakan hasil penjumlahan num1 dan num2 yang menghasilkan nilai
23. Kemudian pada baris ke-6 sampai dengan ke-11 terdapat konstruksi while, dengan pemeriksaan
kondisi dilakukan baris ke-6 :
Pada pemeriksaan pertama kali, num3 memiliki nilai 23, dan num1 memiliki nilai 0, sehingga boolean
expression num3 > num1 bernilai true. Oleh karena itu code block pada baris ke-7 sampai ke-10
dieksekusi. Pada baris ke-7, nilai num2 diperbaharui dengan mengurangkan nilai num2 semula dengan
3. Pada baris ke-8, nilai num1 diperbaharui dengan menambahkan nilai num1 tersebut dengan 2. Pada
baris ke-9, nilai num3 diperbaharui dengan mengambil hasil penjumlahan num1 dan num2. Proses
pembaharuan nilai ketiga variabel num1, num2, dan num3 dapat dilihat pada Tabel 9.1
73
Tabel 9.1
Proses Pembaharuan num1, num2, dan num3
num1
num2
num3
( sebelum loop
dimulai )
23
23
20
22
true
17
21
true
14
20
true
11
19
true
10
18
true
12
17
true
15
17
true
18
-1
17
false
Loop ke0
Contoh 9.1
public class Contoh9_1 {
public static void main(String[] args){
int num1 = 0;
int num2 = 23;
int num3 = num1+num2;
while(num3 > num1){
num2-=3;
num1+=2;
num3 = num1+num2;
System.out.println(num1=+num1 +,num3=+num3);
}
}
}
EKSPERIMEN
1.
2.
b.
Pada Contoh 9.2 diperlihatkan boolean_expression yang langsung diberi nilai true, sehingga sampai
kapanpun boolean_expression ini tidak akan pernah bernilai false. Akibatnya, pengulangan akan terus
dieksekusi sampai jumlah pengulangan yang tidak terbatas.
74
Agar pengulangan menjadi berhingga, maka harus ada tambahan pemeriksaan kondisi di dalam blok
while yang akan mengakibatkan pengulangan berakhir. Solusi ini diperlihatkan pada baris ke-7 sampai
ke-9. Pada baris ke-7 diperlihatkan pemeriksaan nilai variable, apakah nilainya lebih kecil daripada 10,
dengan pernyataan :
if (variable<10)
Jika pemeriksaan ini menghasilkan nilai true, maka baris ke-8 akan dieksekusi.
Contoh 9.2
public class Contoh9_2 {
public static void main(String[] args){
int variable = 20;
while(true){
System.out.println(Nilai variable = +variable);
--variable;
if(variable<10){
break;
}
}
}
}
EKSPERIMEN
3.
Hilangkanlah baris ke-7 sampai ke-9. Catat apa yang terjadi. Mengapa demikian ?
bagian inisialisasi, yang berisi pernyataan pemberian nilai awal untuk suatu variabel parameter;
b.
bagian boolean_expression, yang berisi pernyataan logika yang akan diperiksa, sebagai syarat
pengulangan terus dilanjutkan. Pengulangan akan dilanjutkan jika nilai ekspresi boolean pada
segmen ini bernilai true.
c.
bagian update, yang berisi pernyataan updating parameter ketika satu putaran pada pengulangan
selesai dieksekusi.
b.
c.
75
Contoh 9.3 menunjukkan penggunaan konstruksi pengulangan for. Pada baris ke-3 diperlihatkan
bahwa :
a.
bagian inisialisasi diisi oleh pernyataan int variable=20. Ini berarti sebelum pengulangan
dilaksanakan, sebuah variabel bernama variabel dideklarasikan dan diinisialisasi dengan nilai 20.
b.
c.
segmen update diisi dengan pernyataan variable-- , yang berarti, untuk 1 kali putaran yang
selesai dieksekusi, nilai variable akan dikurangi 1.
Contoh 9.3
public class Contoh9_3 {
public static void main(String[] args){
for(int variable=20; variable>=10;variable--){
System.out.println(Nilai variable = + variable);
}
}
}
Tabel 9.2
Pembaharuan Nilai Variabel
Pengulangan ke-
variable
variable >= 10
20
true
19
true
18
true
17
true
16
true
15
true
14
true
13
true
12
true
11
true
10
10
true
11
false
EKSPERIMEN
4.
76
Contoh 9.4 memperlihatkan bagian inisialisasi yang diisi dengan inisialisasi lebih dari 1 variabel, yaitu
variable1 = 20 dan variable2 = 0. Selain itu juga bagian update diisi dengan pernyataan
update dari kedua variabel tersebut ( baris ke-3 dan ke-4 ). Kondisi yang dinyatakan dalam bagian
boolean_expression adalah variable1>=10 && variable2<=5.
Contoh 9.4
public class Contoh9_4{
public static void main(String[] args){
for(int variable1=20, variable2=0; variable1>=10&&
variable2<=5;variable1--,variable2++){
System.out.println(Nilai variable1= + variable1);
System.out.println(Nilai variable2= +variable2);
}
}
}
Tabel 9.3
Progress Looping pada Contoh 9.4
variable2
variable1>=10
variable2<=5
variable1>=10
variable1
Pengulangan
20
true
true
true
19
true
true
true
18
true
true
true
17
true
true
true
16
true
true
true
15
true
true
true
14
true
false
false
( keluar dari loop )
ke-
&&
variable2<=5
Pada Contoh 9.5 diperlihatkan penggunaan konstruksi pengulangan for dengan semua bagiannya
tidak terisi. Bentuk ini sama dengan while(true), yang akan mengakibatkan terjadinya pengulangan
tak berhingga.
Sama halnya dengan kasus while pada Contoh 9.2, bentuk for( ; ; ) mensyaratkan adanya
tambahan pemeriksaan kondisi pada code_block-nya, supaya pengulangan memiliki jumlah
pengulangan yang berhingga. Seperti yang terjadi pada baris ke-7, pengulangan akan berhenti ketika
nilai variable < 10.
Contoh 9.5
public class Contoh9_5{
public static void main(String[] args){
int variable = 20;
for( ;
; ){
System.out.println(Nilai variable1= +variable);
variable--;
if(variable<10)break;
}
}
}
77
b.
Pada Contoh 9.6 diperlihatkan penggunaan konstruksi do/while. Pada baris ke-3, dilakukan deklarasi
dan inisialisasi variabel bernama variable dengan nilai 20. Kemudian pengulangan akan dilakukan
satu kali, lalu dilakukan pemeriksaan boolean_expression. Karena boolean_expression pada baris ke-7
bernilai false, maka pengulangan tidak dieksekusi lagi.
Pada konstruksi while, jika boolean_expression diset : variable > 20, maka pengulangan tidak
akan dilakukan. Berbeda halnya dengan konstruksi pengulangan do/while, dengan
boolean_expression yang sama, pengulangan akan dilakukan satu kali sebelum akhirnya proses keluar
dari blok pengulangan.
Contoh 9.6
public class Contoh9_6{
public static void main(String[] args){
int variable = 20;
do{
System.out.println(Nilai variable1= + variable);
variable--;
}while(variable>20);
}
}
Nilai variable = 20
Contoh 9.7
public class Contoh9_7{
public static void main(String[] args){
int j=0;
for(int i=0;i<5;i++){
while(j<5){
System.out.print(" @ ");
j++;
}
j=0;
System.out.print("\n");
}
}
}
78
Contoh 9.7 akan menghasilkan sebuah bujursangkar dengan panjang 5 karakter dan lebar 5 karakter,
sebagai berikut :
@@@@@
@@@@@
@@@@@
@@@@@
@@@@@
Contoh 9.8
public class Continue{
public static void main(String[] args){
for(int i=0;i<10;i++){
System.out.print(i + " ");
if (i%2 == 0) continue;
System.out.println( );
}
}
}
Pada contoh 9.8 digunakan System.out.print untuk mencetak variabel i tanpa pindah baris.
Kemudian digunakan operator modulus (%) untuk memeriksa apakah indeksnya genap atau ganjil. Jika
genap, pengulangan dilanjutkan tanpa mencetak perpindahan baris. Hal ini berarti pernyataan
System.out.ptintln( ) tidak dieksekusi atau dilewatkan dan program melanjutkan ke iterasi
berikutnya atau ke nilai i berikutnya.
Sebagaimana halnya pernyataan break, pernyataan continue dapat dilengkapi dengan label untuk
menentukan pengulangan mana yang harus dilanjutkan. Pernyataan continue pada contoh di bawah
ini menghentikan perulangan j dan meneruskan iterasi selanjutnya pada perulangan i.
Contoh 9.9
public class ContinueLabel{
public static void main(String[] args){
outer :
for(int i=0;i<10;i++){
for (int j=0;j<10;j++){
if (j>i){
System.out.println( );
continue outer;
}
System.out.print( + (i*j));
}
}
System.out.println();
}
}
79
While digunakan untuk membuat iterasi dengan jumlah iterasi yang tidak pasti dan untuk iterasi
dari nol sampai beberapa kali;
b.
Do/While, digunakan untuk membuat iterasi dengan jumlah iterasi yang tidak pasti, dan untuk
iterasi dari satu sampai beberapa kali. Pada pengulangan ini pernyataan di dalam blok pengulangan
dijamin dieksekusi minimal satu kali;
c.
For, lebih tepat digunakan untuk membuat iterasi dengan jumlah iterasi yang pasti dan berhingga.
EKSPERIMEN
5.
0
0 1
0 2 4
0 3 6 9
0 4 8 12 16
0 5 10 15 20 25
0 6 12 18 24 30 36
0 7 14 21 28 35 42 49
0 8 16 24 32 40 48 56 64
0 9 18 27 36 45 54 63 72 81
80
10
MENGGUNAKAN METHOD
Method adalah satu kontainer pada kelas yang memuat baris-baris kode. Semua baris kode pada
pemrograman Java harus berada pada blok method, dan semua method harus berada di dalam blok
kelas. Method biasanya digunakan untuk mengenkapsulasi proses-proses yang diperlukan untuk
membentu suatu fungsi/tugas tertentu. Contoh method dapat dianalogikan dengan sebuah fungsi
matematika :
F(x,y)=x+y
Fungsi matematika ini, jika digunakan dalam operasi matematika :
b=F(2,4)
akan menghasilkan nilai 6, karena pada definisi F ( x , y ), dinyatakan bahwa kedua parameter yang
dilewatkan ke dalam fungsi, yaitu x dan y, akan dijumlahkan. Oleh karena itu, nilai 2 dan 4 yang
dilewatkan ke fungsi F akan dijumlahkan, sehingga menghasilkan nilai 2 + 4 = 6. Nilai 6 tersebut akan
menjadi nilai variabel b.
[modifiers] merepresentasikan kata kunci teknologi Java yang memodifikasi cara penggunaan
method. Contoh : public, protected, private, static, final;
b.
return_type adalah tipe nilai yang akan dikembalikan oleh method yang akan digunakan pada
bagian lain dari program. Return_type pada method sama dengan tipe data pada variabel.
Return_type dapat merupakan tipe data primitif maupun tipe data referensi;
c.
d.
e.
81
Contoh 10.1
public void konversiCelciusKeReaumur( ){
celcius = 78;
reaumur = 4/5*celcius ;
System.out.println(Nilai Celcius = + celcius);
System.out.println(Nilai Reaumur = +reaumur);
}
Pada Contoh 10.1 diperlihatkan bahwa method konversiCelciusKeReaumur() tidak memiliki
argumen, dan return-value-nya adalah void, yang berarti, fungsi ini tidak mengembalikan nilai apaapa. Method tersebut hanya melakukan pemberian nilai 78 kepada variabel celcius ( diasumsikan
telah dideklarasikan di luar method ), dan melakukan perhitungan nilai variabel reaumur (variabel
reaumur diasumsikan telah dideklarasikan di luar method).
EKSPERIMEN
1.
2.
Contoh 10.2 merupakan satu contoh aplikasi yang memperlihatkan proses penyimpanan dan
pengambilan pada pada sebuah Lumbung Padi. Pada kelas LumbungPadi, terdapat 3 instance
variable / variabel anggota, yaitu :
a.
b.
c.
b.
c.
ambilPadi() yang akan melakukan pembaharuan nilai variabel padiDiambil dengan rumus:
padiDiambil = padiDiambil + beratPadiYangDiambil
dengan beratPadiYangDiambil = 50.
82
d.
e.
cetakPersediaan(), yang akan mencetak ke layar monitor jumlah padi yang tersimpan di
lumbung.
beratPanenan, yang memuat informasi tentang berat panenan yang dituai oleh petani.
b. lumbung, yang memuat informasi tentang lumbung yang akan dijadikan tempat menyimpan
panenan oleh petani.
Kelas Petani juga mempunyai method-method, yaitu :
a.
b.
c.
Sedangkan kelas KegiatanPanen merupakan kelas main, yaitu class yang mendefinisikan method
main. Pada kelas KegiatanPanen terdapat method main yang berisi pernyataan-pernyataan yang
menggambarkan kegiatan panen. Pada baris ke-4 sampai ke-6 dilakukan deklarasi dan inisialisasi obyekobyek lumbungDesaSukatani ( kelas : LumbungPadi ), pakBakri ( kelas : Petani ), dan
daengBaso( kelas: Petani ).
Pada baris ke-8 dan ke-9, dilakukan inisialisasi variabel lumbung pada obyek pakBakri dan
daengBaso yang referensinya disamakan dengan referensi obyek lumbungDesaSukatani.
Pada baris ke-10, pak Bakri melakukan panen. Hal ini diimplementasikan dengan pemanggilan method
lakukanPanen() milik obyek pakBakri. Kemudian pada baris ke-11, pak Bakri melakukan
penyimpanan
hasil
panen,
yang
diimplementasikan
dengan
pemanggilan
method
simpanPanenanDiLumbung() milik obyek pakBakri. Kemudian pada baris ke-12, pak Bakri
melakukan pengambilan hasil panen, yang diimplementasikan dengan pemanggilan method
ambilPanenanDariLumbung() milik obyek pakBakri.
Pada baris ke-14, Daeng Baso melakukan panen, yang diimplementasikan dengan pemanggilan method
lakukanPanen() milik obyek daengBaso. Kemudian pada baris ke-15, Daeng Baso melakukan
penyimpanan
hasil
panen,
yang
diimplementasikan
dengan
pemanggilan
method
simpanPanenandiLumbung() milik obyek daengBaso.
Contoh 10.2
//file : LumbungPadi.java
public class LumbungPadi{
public int persediaan = 0;
public int padiDisimpan = 0;
public int padiDiambil = 0;
public void hitungPersediaan( ){
persediaan = padiDisimpan padiDiambil;
}
public void simpanPadi( ){
int tambahanPadi = 100;
padiDisimpan = padiDisimpan + tambahanPadi;
}
83
new LumbungPadi ( );
pakBakri.lumbung = lumbungDesaSukaTani;
daengBaso.lumbung = lumbungDesaSukaTani;
pakBakri.lakukanPanen( );
pakBakri.simpanPanenanDiLumbung( );
pakBakri.ambilPanenanDariLumbung( );
daengBaso.lakukanPanen( );
daengBaso.simpanPanenanDiLumbung( );
lumbungDesaSukatani.cetakPersediaan( );
}
}
EKSPERIMEN
84
3.
4.
Buatlah 1 obyek LumbungPadi lagi dan lakukan interaksi dengan obyek-obyek petani
yang sudah ada. Lalu cetaklah persediaan padi di lumbung padi baru ini. Catatlah
hasilnya.
keterangan :
a.
b.
c.
<method identifier([arguments])>;
keterangan :
a.
method identifier adalah nama method. Nama method harus merupakan nama yang terdefinisi
pada kelas yang menjadi cetak biru dari obyek.
b.
arguments adalah nama argumen-argumen. Komposisi argumen pada method yang dipanggil,
harus sama dengan komposisi argumen pada definisi method pada kelas yang menjadi cetak biru
dari obyek.
85
simpanPadi(int tambahanPadi)
b.
ambilPadi(int beratPadiYangDiambil)
simpanPanenanDiLumbung(int jumlahPanenan)
b.
ambilPanenanDariLumbung(int panenanDiambil)
Dengan adanya method dengan argumen, pada method main (), banyaknya padi yang akan disimpan
/ diambil dapat ditentukan dengan lebih bebas. Contohnya adalah kelas KegiatanPanen pada
Contoh 10.3 baris ke-11, 12 dan 15.
Contoh 10.3
//file : LumbungPadi.java
public class LumbungPadi{
public int persediaan = 0;
public int padiDisimpan = 0;
public int padiDiambil = 0;
public void hitungPersediaan( ){
persediaan = padiDisimpan padiDiambil;
}
public void simpanPadi(int tambahanPadi){
padiDisimpan = padiDisimpan + tambahanPadi;
}
public void ambilPadi (int beratPadiYangDiambil){
padiDiambil = padiDiambil + beratPadiYangDiambil;
}
public int hitungPersediaanPadi( ){
persediaan = padiDisimpan padiDiambil;
return persediaan;
}
public void cetakPersediaan( ){
int persediaanPadiTerakhir = hitungPersediaanPadi( );
System.out.println( Persediaan di lumbung =
+ persediaanPadiTerakhir);
}
}
86
//file : Petani.java
public class Petani{
public int beratPanenan;
public LumbungPadi lumbung = new LumbungPadi( );
public void lakukanPanen ( ){
beratPanenan = 150;
}
public void simpanPanenanDiLumbung(int jumlahPanenan ){
lumbung.simpanPadi(jumlahPanenan);
}
public void ambilPanenanDariLumbung(int panenanDiambil){
lumbung.ambilPadi( panenanDiambil);
}
}
//file KegiatanPanen.java
public class KegiatanPanen{
public static void main(String[ ] args){
LumbungPadi lumbungDesaSukatani = new LumbungPadi ( );
Petani pakBakri = new Petani( );
Petani daengBaso = new Petani( );
pakBakri.lumbung = lumbungDesaSukatani;
daengBaso.lumbung = lumbungDesaSukatani;
pakBakri.lakukanPanen();
pakBakri.simpanPanenanDiLumbung(100 );
pakBakri.ambilPanenanDariLumbung( 10);
daengBaso.lakukanPanen( );
daengBaso.simpanPanenanDiLumbung(90);
lumbungDesaSukatani.cetakPersediaan( );
}
}
EKSPERIMEN
5.
Buatlah beberapa obyek Petani baru dan beberapa obyek LumbungPadi baru, dan
buatlah interaksi antara obyek-obyek Petani dan LumbungPadi sebanyak mungkin.
Cetaklah persediaan masing-masing lumbung padi.
keterangan :
a.
[modifiers] merepresentasikan kata kunci pada teknologi Java yang memodifikasi cara-cara
penggunaan method. Contoh : public, protected, private, static, final;
87
b.
return_type adalah tipe nilai yang akan dikembalikan oleh method yang akan digunakan pada
bagian lain dari program. Return_type pada method sama dengan tipe data pada variabel.
Return_type dapat merupakan tipe data primitif maupun tipe data referensi;
c.
d.
e.
f.
Contoh deklarasi method dengan argumen dapat dilihat pada kelas LumbungPadi pada Contoh 10.3
baris berikut :
public void ambilPadi (int beratPadiYangDiambil){
padiDiambil = padiDiambil + beratPadiYangDiambil;
}
keterangan :
a.
[modifiers] merepresentasikan kata kunci pada teknologi Java yang memodifikasi cara-cara
penggunaan method. Contoh : public, protected, private, static, final;
b.
return_type adalah tipe nilai yang akan dikembalikan oleh method yang akan digunakan pada
bagian lain dari program. Return_type dapat merupakan tipe data primitif maupun tipe data
referensi;
88
c.
d.
e.
f.
g.
Contoh
deklarasi
method
yang
mengembalikan
nilai
adalah
hitungPersediaanPadi() pada kelas LumbungPadi pada Contoh 10.3.
pada
method
method membuat program lebih mudah dibaca dan mudah untuk dipelihara. Misalnya pada kelas
LumbungPadi, method cetakPersediaan() akan lebih mudah dimengerti daripada :
int persediaanPadiTerakhir = hitungPersediaanPadi( );
System.out.println(Persediaan di lumbung = + persediaanPadiTerakhir);
Anggap saja, pada kelas KegiatanPanen tidak dilakukan pemanggilan method, tetapi menjabarkan
semua kegiatan pada method-method tersebut, seperti pada Contoh 10.4. Ketika programmer ingin
melakukan perbaikan pada kegiatan pengambilan padi yang dilakukan oleh obyek pakBakri, dia
harus menganalisis dulu baris-baris mana saja yang termasuk dalam kegiatan yang ingin diperbaiki.
Kesulitan ini akan teratasi jika programmer mengelompokkan pernyataan-pernyataan pada Contoh
10.4 menjadi method-method seperti pada Contoh 10.3;
b.
method membuat proses pengembangan dan perawatan menjadi lebih cepat. Jika programmer
ingin melakukan penambahan kegiatan yang dapat dilakukan pada kelas Petani, maka
programmer dapat membuat sebuah method dan menjabarkan proses-proses yang dibutuhkan
dalam method tersebut. Ketika tiba waktunya pemeliharaan, proses perbaikan akan terasa lebih
cepat dibandingkan dengan, misalnya, menjabarkan proses-proses tanpa membuat method dengan
menuliskan pernyataan-pernyataan pada method main();
89
c.
method merupakan dasar untuk melakukan membuat piranti lunak yang re-usable. Terkadang ada
program lain yang membutuhkan method-method pada kelas Petani. Program itu dapat
menggunakan method-method tersebut setiap kali membutuhkan;
d.
Contoh 10.4
//file KegiatanPanen.java
public class KegiatanPanen{
public static void main(String[ ] args){
LumbungPadi lumbungDesaSukatani = new LumbungPadi();
Petani pakBakri = new Petani( );
Petani daengBaso = new Petani( );
pakBakri.lumbung = lumbungDesaSukatani;
daengBaso.lumbung = lumbungDesaSukatani;
pakBakri.beratPanenan=150;
int jumlahPanenan = 100;
pakBakri.lumbung.padiDisimpan =
pakBakri.lumbung.padiDisimpan + jumlahPanenan;
int panenanDiambil = 10;
pakBakri.lumbung.padiDiambil=
pakBakri.lumbung.padiDiambil + panenanDiambil;
daengBaso.beratPanenan=150;
jumlahPanenan = 90;
daengBaso.lumbung.padiDisimpan=
daengBaso.lumbung.padiDisimpan+ jumlahPanenan;
lumbungDesaSukatani.persediaan=
lumbungDesaSukatani.padiDisimpan
lumbungDesaSukatani.padiDiambil;
int persediaanPadiTerakhir =
lumbungDesaSukatani . persediaan;
System.out.println( Persediaan di lumbung = +
persediaanPadiTerakhir);
}
}
EKSPERIMEN
6.
7.
Buatlah modifikasi :
a. Setiap kali panen, pakBakri hanya mendapatkan 30 kilogram
b. Setiap kali panen, daengBaso mendapatkan 60 kilogram
c. Setiap kali mengambil padi dari lumbung, pakBakri mengambil 20 kilogram, sedangkan
daengBaso mengambil 15 kilogram.
Apakah memperbaiki program yang tidak menggunakan method dirasakan cukup mudah ?
90
10.21
Suatu kelas dapat mengandung beberapa method dengan nama yang sama tetapi dengan komposisi
argumen yang berbeda. Perhatikan kelas Petani pada Contoh 10.5.
Ada sedikit perubahan pada Contoh 10.5. Perhatikan pada kelas KegiatanPanenan. Sekarang
didefinisikan terdapat 2 buah obyek LumbungPadi, yaitu : lumbungDesaSukatani dan
lumbungDesaSukamaju.
Perubahan lainnya adalah : obyek pakBakri mempunyai lumbung default, yaitu
lumbungDesaSukamaju, sedangkan obyek daengBaso mempunyai lumbung default, yaitu
lumbungDesaSukatani.
Perubahan berikutnya adalah pada kelas Petani. Pada kelas ini terdapat 3 buat method
simpanPanenanDiLumbung(), yaitu :
a.
b.
c.
Perhatikan kelas KegiatanPanenan. Pada method main(), proses interaksi antara obyek
pakBakri
dengan lumbung lumbungPadiSukatani
dan lumbungPadiSukamaju
diperlihatkan pada baris ke-12 sampai baris ke-15. Proses interaksi antara obyek daengBaso dengan
kedua lumbung tersebut diperlihatkan pada baris ke-19. Proses pada tiap baris digambarkan pada Tabel
10.1 berikut ini.
Tabel 10.1.
Proses pada Contoh 10.4
padiDiambil
padiDisimpan
padiDiambil
lumbungPadiSukamaju
padiDisimpan
lumbungPadiSukatani
12
10
13
60
14
40
60
15
40
60
10
16
130
60
10
Baris ke-
91
Contoh 10.5
//file : LumbungPadi.java
public class LumbungPadi{
public int persediaan = 0;
public int padiDisimpan = 0;
public int padiDiambil = 0;
public void hitungPersediaan( ){
persediaan = padiDisimpan - padiDiambil;
}
public void simpanPadi(int tambahanPadi){
padiDisimpan = padiDisimpan + tambahanPadi;
}
public void ambilPadi (int beratPadiYangDiambil){
padiDiambil = padiDiambil + beratPadiYangDiambil;
}
public int hitungPersediaanPadi( ){
persediaan = padiDisimpan - padiDiambil;
return persediaan;
}
public void cetakPersediaan( ){
int persediaanPadiTerakhir = hitungPersediaanPadi( );
System.out.println("Persediaan di lumbung = " + persediaanPadiTerakhir);
}
}
//file : Petani.java
public class Petani{
public int beratPanenan;
public LumbungPadi lumbung;
public void lakukanPanen ( ){
beratPanenan = 150;
}
public void simpanPanenanDiLumbung(){
lumbung.simpanPadi(50);
}
public void simpanPanenanDiLumbung(int jumlahPanenan ){
lumbung.simpanPadi(jumlahPanenan);
}
public void simpanPanenanDiLumbung(int jumlahPanenan, LumbungPadi lb){
lb.simpanPadi(jumlahPanenan);
}
public void ambilPanenanDariLumbung(int panenanDiambil){
lumbung.ambilPadi( panenanDiambil);
}
}
//file : KegiatanPanen.java
public class KegiatanPanen{
public static void main(String[ ] args){
LumbungPadi lumbungDesaSukatani = new LumbungPadi ( );
LumbungPadi lumbungDesaSukamaju = new LumbungPadi( );
Petani pakBakri = new Petani( );
Petani daengBaso = new Petani( );
pakBakri.lumbung = lumbungDesaSukamaju;
daengBaso.lumbung = lumbungDesaSukatani;
pakBakri.lakukanPanen();
pakBakri.simpanPanenanDiLumbung(10);
pakBakri.simpanPanenanDiLumbung();
pakBakri.simpanPanenanDiLumbung(40, lumbungDesaSukatani);
pakBakri.ambilPanenanDariLumbung(10);
daengBaso.lakukanPanen( );
daengBaso.simpanPanenanDiLumbung(90);
lumbungDesaSukatani.cetakPersediaan( );
lumbungDesaSukamaju.cetakPersediaan( );
}
}
92
10.22
Pada Java API terdapat method-method yang di-overload. Misalnya pada kelas PrintStream,
terdapat method yang dioverload antara lain :
a.
print(boolean b)
b.
print(char c)
c.
print(char[ ] s)
d.
print(double d)
e.
print(float f)
f.
print(int i)
g.
print(long l)
h.
print(Object o)
i.
print(String s)
93
94
11
95
//file KegiatanPanen.java
public class KegiatanPanen{
public static void main(String[ ] args){
Petani pakBakri = new Petani( );
Petani daengBaso = new Petani( );
pakBakri.lakukanPanen();
pakBakri.simpanPanenanDiLumbung(100 );
pakBakri.ambilPanenanDariLumbung( 10);
daengBaso.lakukanPanen( );
daengBaso.simpanPanenanDiLumbung(90);
LumbungPadi.cetakPersediaan( );
}
}
EKSPERIMEN
1.
2.
keterangan :
a.
[modifiers] merepresentasikan kata kunci pada teknologi Java yang memodifikasi cara-cara
penggunaan method. Contoh : public, protected, private, final;
b.
static adalah kata kunci pada teknologi Java yang menandakan bahwa method tersebut adalah
method statik. Catatan : static sebenarnya juga merupakan modifier, tetapi dalam sintak
method statik, static merupakan kata kunci yang wajib dituliskan;
c.
return_type adalah tipe nilai yang akan dikembalikan oleh method yang akan digunakan pada
bagian lain dari program. Return_type pada method sama dengan tipe data pada variabel.
Return_type dapat merupakan tipe data primitif maupun tipe data referensi;
d.
e.
f.
96
Contoh pemanggilan method statik adalah pada kelas KegiatanPanen pada baris ke-11 :
LumbungPadi.cetakPersediaan( );
[modifiers] merepresentasikan kata kunci pada teknologi Java yang memodifikasi cara-cara
penggunaan variabel. Contoh : public, protected, private, final;
b.
static adalah kata kunci pada teknologi Java yang menandakan bahwa variabel tersebut adalah
variabel statik;
c.
data_type adalah tipe data, dapat berupa tipe data primitif, maupun tipe data referensi;
d.
e.
Contoh deklarasi dan inisialisasi variabel statik, adalah pada kelas LumbungPadi pada baris ke-2 :
public class LumbungPadi{
public static int persediaan = 0;
...
}
97
b.
public static
public static
public static
public static
dan lainnya.
double
double
double
double
abs
cos
exp
max
(double
(double
(double
(double
a);
a);
a);
a, double b);
Method main() mempunyai argumen berupa array String args. Array String ini akan diisi
nilai-nilai yang dimasukkan ketika program dipanggil. Sebagai contoh, ketika program
KegiatanPanen dipanggil dengan menyertakan argumen :
C:> java KegiatanPanen
petani1
petani2
petani3
98
Contoh 11.2
public class Count1 {
private int serialNumber;
private static int counter = 0;
public Count1() {
counter++;
serialNumber = counter;
}
}
Dalam contoh 11.2 di atas, diberikan SerialNumber yang unik untuk setiap obyek yang dibuat,
dimulai dengan angka 1 untuk obyek pertama, angka 2 untuk obyek kedua, dan seterusnya. Variable
counter di-share/dibagi untuk semua instance. Ketika membuat sebuah obyek Count, konstruktor
akan dipanggil. Pemanggilan konstruktor ini akan me-increment (menambahkan dengan 1) nilai dari
variabel counter dan nilai ini diberikan kepada variabel serialNumber. Gambar 11.1 berikut ini
menunjukkan visualisasi dari pembentukan instance/obyek tersebut.
Variabel statik memiliki konsep yang serupa dengan variabel global di dalam bahasa pemrograman
lainnya. Bahasa Java tidak mengenal variabel global, tetapi variabel statik adalah sebuah variabel yang
dapat diakses oleh setiap instance dari sebuah kelas. Jika variabel statik di atas (counter) tidak
dideklarasikan private, maka variabel tersebut dapat diakses dari luar kelas. Untuk mengkasesnya
tidak diperlukan instance dari kelasnya, tetapi menggunakan nama kelasnya sebagaimana ditunjukkan
pada contoh kode program berikut ini.
Contoh 11.3
public class OtherClass {
public void incrementNumber() {
Count1.counter++;
}
}
99
Terkadang perlu juga mengakses kode program yang tidak memiliki instance dari sebuah kelas. Hal
tersebut dapat dilakukan dengan menggunakan method yang dideklarasikan static. method
demikian seringkali disebut sebagai method kelas sebagaimana ditunjukkan pada kode program berikut.
Contoh 11.4
public class Count2 {
private int serialNumber;
private static int counter = 0;
public static int getTotalCount() {
return counter;
}
public Count2() {
counter++;
serialNumber = counter;
}
}
Untuk menggunakan method yang dideklarasikan static, tidak perlu menggunakan referensi
obyeknya melainkan nama kelas seperti ditunjukkan pada kode program berikut ini :
Contoh 11.5
public class TestCounter {
public static void main(String[] args) {
System.out.println("number of counter is "+
Count2.getTotalCount());
Count2 count1 = new Count2();
System.out.println("number of counter is "+
Count2.getTotalCount());
}
}
Contoh 11.6
public class Count3 {
private int serialNumber;
private static int counter = 0;
public static int getSerialNumber() {
return serialNumber; //COMPILER ERROR
}
}
100
Hal yang harus diperhatikan ketika menggunakan method statik antara lain :
Method statik tidak dapat di-override, tetapi dapat disembunyikan.
Method main() merupakan sebuah method statik karena JVM tidak perlu membuat sebuah
instance dari kelas yang bersangkutan ketika method main() dieksekusi. Jika mempunyai data
member, hendaknya dibuatkan sebuah obyek untuk mengaksesnya.
b.
c.
d.
Method atau variabel secara logika bukan milik dari sebuah obyek, tetapi milik sebuah kelas
utilitas. Contohnya kelas Math pada Java API.
101
102
12
KONSEP PEMROGRAMAN
BERORIENTASI OBYEK DENGAN JAVA
12.4.1
Package
Package container
shipping
Package name
GUI
domain
Company
Subpackage
Vehicle
Truck
reports
Class in a package
12.4.2
Diagram kelas (Class diagram) merepresentasikan struktur statik dari sebuah sistem, di mana diagram
ini terdiri dari kelas-kelas dan hubungan yang ada di antaranya.
Simpul kelas (Class node) merupakan representasi grafis dari sebuah kelas. Gambar di bawah ini adalah
contoh dari class node, di mana ia berupa nama kelas yang diletakkan di dalam kotak. Contoh (a), (b),
dan (c) merupakan contoh class node yang hanya berupa nama kelasnya saja. (Contoh (a) merupakan
bentuk dari kelas konkrit yang anggotanya tidak turut dimodelkan. Contoh (b) merupakan kelas abstrak
dengan nama kelas yang dicetak miring dan contoh (c) merupakan sebuah interface). konsep akan kelas
abstrak dan interface akan dibahas kemudian. Sementara contoh (d) menggambarkan sebuah kelas
lengkap dengan atribut dan methodnya.
103
a.
b.
c.
<<interface>>
Set
InputStream
Company
d.
+
+
+
Vehicle
load : double = 0.0
maxLoad : double
getLoad() : double
getMaxLoad() : double
addBox(weight:double) : boolean
Sebuah bentuk class node yang lengkap diperlihatkan dalam Gambar 12.3. Class node berbentuk
sebuah kotak yang dibagi menjadi tiga bagian. Bagian pertama berisikan nama kelas, bagian kedua
berisi atribut, dan bagian ketiga berisi method-method dalam kelas.
Pada bagian deklarasi atribut (bagian kedua), sebuah atribut dicirikan dengan elemen mode akses
(access modifier), nama atribut, tipe data, dan nilai inisialnya. Pemberian nilai inisial ini bersifat
opsional. Sedangkan, pada bagian deklarasi method, sebuah method dicirikan dengan elemen access
modifier, nama method, nama parameter, tipe parameter, dan tipe kembalian dari method.
Attribute
name
+
+
+
+
#
Access modes
Attribute type
Attribut
initial value
Class name
Vehicle
load : double = 0.0
maxLoad : double
getLoad() : double
getMaxLoad() : double
setMaxLoad(max : double)
addBox(weight : double): boolean
calcEngineEfficiency():double
Param type
attributes
methods
Return type
Simbol-simbol yang digunakan sebagai access modifier dalam UML adalah sebagai berikut :
Tabel 12.1
Simbol untuk Mode Akses
Mode akses
Simbol
private
protected
public
default
Konsep tentang access modifier sendiri akan dibahas kemudian. Hal yang perlu diperhatikan adalah
untuk access modifier default, tidak digunakan simbol apapun (blank).
Gambar 12.4 berikut ini merupakan sebuah contoh dari class node yang memiliki elemen statik. Hal ini
ditunjukkan dengan garis bawah pada elemen bersangkutan. Sebagai contoh, counter merupakan
data atribut statik dan getTotalCount merupakan method statik.
104
+
+
Count
counter : int = 0
instanceNumber : int
getTotalCount()
getMyNumber()
12.5 Inheritance
Dalam pemrograman, seringkali dibuatkan suatu model untuk suatu obyek (model untuk seorang
karyawan misalnya), dan membutuhkan tipe yang lebih spesifik dari model awal tersebut. Sebagai
contoh, model seorang manager. Seorang manajer adalah karyawan plus beberapa atribut tambahan.
Misalnya, dibuatkan sebuah model UML seorang karyawan (Employee) dalam bentuk kelas sebagai
berikut :
Employee
name : String = ""
salary : double
birthDate : Date
getDetails() : String
+
+
+
+
Dalam bentuk kode bahasa Java, bagan di atas dapat diterjemahkan sebagai berikut:
Contoh 12.1
public class Employee {
public String name = ;
public double salary;
public Date birthDate;
public String getDetails() {}
}
Selain itu, dapat juga dibuatkan sebuah model UML untuk seorang Manager dengan bentuk sebagai
berikut:
+
+
+
+
+
Manager
name : String = ""
salary : double
birthDate : Date
department : String
getDetails() : String
Gambar 12.6 Model kelas Manager.
Model Manager di atas dalam kode bahasa Java diterjemahkan sebagai berikut :
105
Contoh 12.2
public class Manager {
public String name = ;
public double salary;
public Date birthDate;
public String department;
public String getDetails() {}
}
Contoh di atas menggambarkan penduplikasian data antara kelas Manager dan kelas Employee. Di
dalam kelas Employee terdapat atribut name, salary, dan birthDate. Begitu juga di dalam kelas
Manager. Selain itu, method getDetails() juga terdapat baik dalam kelas Employee maupun
Manager. Contoh ini adalah contoh rancangan yang tidak baik. Untuk membuat rancangan kelas yang
lebih baik, perlu dibuatkan sebuah kelas baru dari kelas yang sudah ada, dalam kasus ini membuat kelas
Manager dari kelas Employee. Proses ini dinamakan subclassing atau inheritance (pewarisan).
Dalam bahasa pemrograman Java, penentuan inheritance dilakukan dengan menggunakan kata kunci
extends, seperti terlihat dalam contoh penggalan program berikut :
Contoh 12.3
public class Manager extends Employee {
public String department;
}
Dalam bentuk diagram UML, hal tersebut akan tergambar sebagai berikut :
Dalam contoh ini, kelas Manager disebut sebagai subclass dan Employee sebagai superclass. Panah
yang menunjuk ke kelas Employee menggambarkan bahwa kelas Manager adalah turunan atau
subclass dari kelas Employee.
Pemrograman Java hanya mengenal single inheritance, yaitu bahwa setiap kelas hanya boleh memiliki
satu superclass. Untuk mengakomodasi multiple inheritance Java menyediakan konsep bernama
interface yang akan dibahas lebih lanjut setelah sub-bab ini. Gambar berikut ini menunjukkan single
inheritance.
106
12.6 Enkapsulasi
Pada pemrograman berorientasi obyek, istilah enkapsulasi berarti menyembunyikan data di dalam
kelas. Data-data yang dimaksud adalah instance variable yang menjadi milik eksklusif dari kelas / obyek.
Sebenarnya, obyek dapat dikatakan sebagai entitas yang mengikat data-data menjadi data-data yang
ekslusif. Pengikatan ini juga disebut enkapsulasi data.
12.3.3
Ketika kode dalam satu kelas (kelas A) memiliki akses ke kelas yang lain (kelas B), hal tersebut berarti
kelas A dapat melakukan satu dari tiga hal berikut :
Membuat instance kelas B;
Meng-extends kelas B (dengan kata lain, menjadi subclass dari kelas A);
Mengakses atribut dan method tertentu dalam kelas B tergantung dari access control atribut dan
methodnya.
Access Modifier yang dapat diterapkan pada kelas adalah akses default dan public.
Dalam deklarasinya, sebuah kelas dengan access modifier default tidak memiliki modifier di depan
nama kelasnya. Kelas yang memiliki akses default berarti kelas ini hanya dapat diakses oleh kelas yang
berada di dalam package yang sama. Contoh, jika kelas A dan B terletak di dalam package yang
berbeda, dan kelas A memiliki akses default, maka kelas B tidak dapat membuat instance dari kelas
A atau bahkan tidak dapat mendeklarasikan variabel yang bertipe kelas A. Perhatikan contoh berikut ini:
Contoh 12.4
package packageOne;
class Animal {}
package packageTwo;
import packageOne.Animal;
class Dog extends Animal {}
Superclass Animal berada di dalam package yang berbeda dengan subclassnya, yaitu Dog.
Pernyataan import di dalam kelas Dog berusaha mengimpor kelas Animal. Ketika proses kompilasi
dijalankan, kelas Animal dapat dikompilasi, tetapi tidak dengan kelas Dog. Hal ini disebabkan karena
superclass Animal mempunyai akses default dan terletak di dalam package yang berbeda.
107
Kelas yang dideklarasikan public dapat diakses oleh kelas yang berada di manapun, termasuk oleh
kelas yang berada di package yang berbeda. Jika contoh kode di atas dimodifikasi dengan menjadikan
kelas Animal memiliki access modifier public, maka kedua kelas tersebut dapat dikompilasi.
Contoh 12.5
package packageOne;
public class Animal {//public modifier
}
Dengan modifikasi tersebut, semua kelas dapat menginstantiasi kelas Animal dan meng-extends
kelas ini kecuali kelas Animal diberi modifier final (pembahasan tentang modifier final ada pada
bagian selenjutnya).
12.3.4
Mode Akses (Access Modifier) pada Class Member (Atribut dan Method)
Mode Akses (Access Modifier) adalah modifier-modifier yang memberi batasan kemampuan variabel
atau method untuk diakses. Ada 4 buah modifier, yaitu public, protected, default, dan
private. Perhatikan contoh di bawah ini.
package1
Class2
OK
OK +
OK #
NO -
a
b
c
d
:
:
:
:
Class1
int
int
int
int
SubClass1
OK
OK
OK
NO
package2
package1
package3
Class2
NO
OK
NO
NO
a
+ b
# c
- d
:
:
:
:
Class1
int
int
int
int
SubClass1
NO
OK
OK
NO
Sebuah variabel atau method yang dideklarasikan public dapat diakses oleh kelas manapun, apakah
kelas tersebut berada di dalam package yang sama atau berbeda.
Pada Gambar 12.9, atribut b dalam kelas Class1 dideklarasikan public. Kelas yang berada dalam
package yang sama (Class2 dan SubClass1) dapat mengakses atribut tersebut.
Pada Gambar 1.9, variabel b dalam kelas Class1 juga dideklarasikan public. Kelas Class2 dan
SubClass1 yang berada di dalam package yang berbeda dapat mengakses variabel b.
108
Modifier public adalah modifier yang memberi kemampuan tak terbatas bagi variabel atau method
untuk diakses. Artinya, variabel atau method yang menggunakan modifier public akan dapat diakses
dari mana saja, baik dari dalam kelas sendiri, maupun dari kelas lain.
Selama ini kita telah membuat variabel dan method dengan modifier public. Permasalahan akan
muncul ketika kita memberikan modifier public pada instance variable / variabel anggota. Perhatikan
Contoh 12.1
Contoh 12.6
// file : LumbungPadi2.java
public class LumbungPadi2{
public int persediaan;
public int jumlahDiambil;
public int jumlahDimasukkan;
public void cetakPersediaan( ){
persediaan = persediaan + jumlahDimasukkan jumlahDiambil;
System.out.println(Persediaan = + persediaan);
}
}
//file : KegiatanPanen2.java
public class KegiatanPanen2{
public static void main(String[ ] args){
LumbungPadi2 lumbungDesaSukatani = new LumbungPadi2( );
lumbungDesaSukatani.persediaan = 100;
lumbungDesaSukatani.jumlahDimasukkan = 200;
lumbungDesaSukatani.jumlahDiambil = 150;
lumbungDesaSukatani.cetakPersediaan( );
}
}
Setelah mengkompilasi kedua file *.java pada Contoh 12.1, eksekusilah! Output yang ditampilkan
adalah Persediaan = -100. Pertanyaannya adalah mungkinkan persediaan padi dapat bernilai -100 ?
Ini adalah contoh masalah yang terjadi jika pada instance variable diterapkan modifier public. Semua
kelas dapat melakukan modifikasi nilai variabel tanpa memperhatikan batasan-batasan yang
seharusnya diberikan kepada variabel tersebut.
Secara logika, persediaan padi pada lumbung mempunyai nilai minimal=0. Rancangan kelas
LumbungPadi seharusnya mengakomodasi pembatasan nilai tersebut.
Sebuah variabel atau method yang dideklarasikan private hanya dapat diakses oleh method yang
merupakan member dari kelas tersebut. Ia tidak dapat diakses oleh kelas lain yang berada di dalam
package yang sama ataupun di lain package.
Sebagai contoh pada Gambar 12.9, atribut d dalam kelas Class1 dideklarasikan private. Akibatnya,
kelas Class2 yang berada dalam package yang sama (package1) tidak dapat mengakses atribut
tersebut. Begitu juga dengan kelas SubClass1 yang merupakan subclass dari kelas Class1 tidak
dapat mengakses variabel d tersebut.
Pada Gambar 12.10, variabel d dalam kelas Class1 juga dideklarasikan private. Kelas Class2
ataupun kelas SubClass1 yang berada di dalam package yang berbeda tidak dapat mengakses
atribut ini.
Modifier private membatasi aksesibilitas variabel atau method sehingga hanya dapat diakses oleh
variabel atau method dari kelas yang sama. Perhatikan Contoh 12.2. Semua instance variable dari kelas
LumbungPadi2 diberi modifier private. Kemudian oleh method main() pada kelas
KegiatanPanen2 variabel-variabel tersebut dimodifikasi nilainya.
109
Contoh 12.7
//file : LumbungPadi2.java
public class LumbungPadi2{
private int persediaan;
private int jumlahDiambil;
private int jumlahDimasukkan;
}
//file : KegiatanPanen2.java
public class KegiatanPanen2{
public static void main(String[ ] args){
LumbungPadi2 lumbungDesaSukatani = new LumbungPadi2( );
lumbungDesaSukatani.persediaan = 100;
lumbungDesaSukatani.jumlahDimasukkan =200;
lumbungDesaSukatani.jumlahDiambil = 150;
lumbungDesaSukatani.cetakPersediaan( );
}
}
Jika kelas LumbungPadi2 dan KegiatanPanen2 dikompilasi, maka akan terjadi error :
Hasil kompilasi memperlihatkan bahwa method main() tidak dapat memodifikasi nilai dari variabel
persediaan, jumlahDimasukkan, jumlahDiambil, dan cetakPersediaan dari obyek
lumbungDesaSukatani. Ini buktu bahwa modifier private menyebabkan instance variable dan
method tidak dapat diakses dari luar kelas / obyek tersebut. Inilah yang disebut enkapsulasi. Data yang
disimpan oleh obyek lumbungDesaSukatani tidak dapat diakses oleh obyek di luar
lumbungDesaSukatani.
Sama dengan access modifier default dalam kelas, sebuah variabel atau method mempunyai hak
akses default jika ia tidak dituliskan secara eksplisit dalam deklarasi. Hak akses yang demikian berarti
akses hanya diizinkan bagi kelas yang berada di dalam package yang sama.
Pada Gambar 12.9, atribut a dalam kelas Class1 dideklarasikan default. Akibatnya, kelas Class2
yang berada dalam package yang sama (package1) dapat mengakses atribut tersebut. Begitu juga
dengan kelas SubClass1 yang merupakan subclass dari kelas Class1 dapat mengakses variabel d
tersebut.
Pada Gambar 12.10, variabel a dalam kelas Class1 juga dideklarasikan default. Kelas Class2
ataupun kelas SubClass1 tidak dapat mengakses atribut ini karena mereka berada di dalam
package yang berbeda.
110
Access modifier protected berarti member dapat diakses oleh kelas yang berada dalam package
yang sama dan subclass yang berada di dalam package yang berbeda.
Pada Gambar 12.9, atribut c dalam kelas Class1 dideklarasikan protected. Akibatnya, kelas
Class2 yang berada dalam package yang sama (package1) dapat mengakses atribut tersebut.
Begitu juga dengan kelas SubClass1 yang merupakan subclass dari kelas Class1 dapat mengakses
variabel d tersebut.
Pada Gambar 12.10, variabel c dalam kelas Class1 juga dideklerasikan protected. Kelas Class2
tidak dapat mengakses atribut ini karena ia berada di package yang berbeda. Tetapi SubClass1
dapat mengakses atribut ini karena meskipun ia berada di dalam package yang berbeda, ia
merupakan subclass dari kelas Class1.
Tabel di bawah ini merupakan rangkuman dari access modifier pada class member.
Tabel 12.2
Aksesibilitas untuk Class Member
Modifier
private
default
protected
public
12.5.3
Kelas
yang
sama
Ya
Ya
Ya
Ya
Package
yang Sama
Ya
Ya
Ya
Subclass
Ya
Ya
Semua
Kelas
Ya
Contoh 12.7 memperlihatkan penggunaan modifier private, data milik obyek terlindungi dari aksesakses dari obyek luar. Lalu bagaimana mengakses dan memodifikasi data tersebut ?
Untuk dapat mengakses data yang dilindungi pada obyek, diperlukan sebuah interface / antarmuka.
Interface tersebut berupa method. Dengan menggunakan method, variabel anggota dapat diakses,
dimodifikasi, dan dibatasi modifikasinya.
Salah satu kegunaan method sebagai interface untuk variabel-variabel anggota adalah : method dapat
berfungsi sebagai filter untuk membatasi nilai variabel-variabel anggota pada kelas, seperti yang
diperlihatkan pada Contoh 12.8.
Contoh 12.8
//file : LumbungPadi2.java
public class LumbungPadi2{
private int persediaan;
private int jumlahDiambil;
private int jumlahDimasukkan;
public void setPersediaan( int p ){
System.out.println(SET PERSEDIAAN PADI);
if( p>= 0){
persediaan = p;
System.out.println(Persediaan diset = +p+\n);
}else{
System.out.println(Persediaan padi harus nol atau positif ) ;
}
System.out.println(========================\n);
}
public int getPersediaan( ){
return persediaan;
}
111
//file : KegiatanPanen2.java
public class KegiatanPanen2{
public static void main(String[ ] args){
LumbungPadi2 lumbungDesaSukatani = new LumbungPadi2( );
lumbungDesaSukatani.setPersediaan(100);
lumbungDesaSukatani.setJumlahDimasukkan(100);
lumbungDesaSukatani.setJumlahDiambil(250);
lumbungDesaSukatani.cetakPersediaan();
}
}
112
a.
menguji apakah nilai argumen yang dilewatkan bernilai negatif. Jika bernilai negatif, maka akan
keluar pesan kesalahan, dan eksekusi akan keluar dari method;
b.
Jika nilai argumen yang dilewatkan bernilai positif, maka dilakukan pengujian apakah besarnya
lebih kecil atau sama dengan persediaan. Jika benar, maka nilai dari argumen akan di-copy ke
variabel jumlahDiambil. Kemudian variabel persediaan diperbaharui dengan rumus :
persediaan = persediaan - jumlahDiambil;
c.
Jika nilai argumen bernilai lebih besar dari variabel persediaan , maka program akan
mengeluarkan pesan kesalahan. Hal ini dilakukan karena secara logika, tidak mungkin permintaan
pengambilan padi melebihi persediaan yang ada.
Dengan penggunaan interface berupa method , maka method pemanggil (caller) tidak perlu melakukan
pemeriksaan terhadap variabel, karena hal itu telah dilakukan oleh method pekerja (worker).
Setelah Contoh 12.8 dikompilasi dan dijalankan, maka output program adalah sebagai berikut :
SET PERSEDIAAN PADI
Persediaan diset = 100
========================
SET JUMLAH PADI YANG DIMASUKKAN KE LUMBUNG
Jumlah Padi Dimasukkan = 100
Persediaan padi = 200
========================
PENGAMBILAN PADI
Tidak tersedia padi dalam jumlah yang diinginkan
Jumlah padi yang diinginkan = 250
Persediaan = 200
========================
CETAK PERSEDIAAN PADI DI LUMBUNG
Persediaan padi = 200
========================
Terlihat bahwa ketika dilakukan pengambilan padi dengan jumlah padi lebih besar dari pada
persediaan, maka program akan melakukan tindakan pemberitahuan bahwa jumlah padi yang ingin
diambil tidak dapat dipenuhi oleh lumbung padi. Dengan demikian variabel anggota dapat dikendalikan
nilainya, dan tidak menyimpang dari rancangan yang sudah ditentukan.
EKSPERIMEN
1. Ubahlah baris ke-5 sampai ke-8 sebagai berikut :
lumbungDesaSukatani.setPersediaan(20);
lumbungDesaSukatani.setJumlahDimasukkan(100);
lumbungDesaSukatani.setJumlahDiambil(80);
Kompilasi dan jalankan program tersebut. Outputnya bagaimana ? Mengapa outputnya
seperti itu ?
2. Ubahlah baris ke-5 sampai ke-8 sebagai berikut :
lumbungDesaSukatani.setPersediaan(-100);
lumbungDesaSukatani.setJumlahDimasukkan(-100);
lumbungDesaSukatani.setJumlahDiambil(-250);
Kompilasi dan jalankan program tersebut. Outputnya bagaimana ? Mengapa outputnya
seperti itu ?
113
instance variable, yaitu variabel yang dapat digunakan pada semua bagian obyek. Misalnya,
variabel tersebut dapat diakses oleh method pada obyek tersebut. Variabel ini adalah variabel
anggota pada kelas, yang dideklarasikan di dalam kelas tetapi di luar method.
b.
local variable, yaitu variabel yang hanya dapat digunakan pada method yang mendeklarasikannya.
Sebagai contoh, method setJumlahDimasukkan() pada Contoh 12.8 mempunyai 2 buah local
variable, yaitu :
a.
pesan (String)
b.
kondisi (boolean)
EKSPERIMEN
3.
Buatlah sebuah method baru untuk mengakses variabel-variabel lokal dan anggota,
sebagai berikut :
public void aksesVariabel( ){
//mengakses variabel jumlahDiambil
System.out.println(Jumlah padi yang diambil = + jumlahDiambil);
//mengakses variabel pesan milik
System.out.println(Bunyi pesan pada method +
setJumlahDimasukkan adalah + pesan);
}
Pada memory, Instance Variable disimpan pada heap memory. Sedangkan Local Variable Stack Memory.
Pada kelas main pada Contoh 12.3, terdapat instanstiasi obyek LumbungPadi yang diberi identifier
lumbungDesaSukatani. Pada stack memory, variabel referensi lumbungDesaSukatani
ditempatkan pada scope yang diberi nama main. Lalu variabel-variabel instans / instance variable milik
lumbungDesaSukatani dialokasikan pada heap memory dan dikelompokkan menjadi obyek
LumbungPadi. Variabel referensi yang berada di stack memory akan berisi alamat memory dari obyek
LumbungPadi tersebut.
Lalu pada method main(), method setPersediaan() milik lumbungDesaSukatani dipanggil.
Pada definisi kelas LumbungPadi, method setPersediaan() memiliki argumen p. Karena
argumen p ini merupakan variabel lokal milik method setPersediaan() maka pada stack memory
dibuatlah scope dengan nama setPersediaan. Argumen p diletakkan pada scope tersebut, dan
diberi nilai 100 karena nilai yang dilewatkan ke method setPersediaan() adalah 100.
Kemudian method main() memanggil method setJumlahDimasukkan() milik obyek
lumbungDesaSukatani. Pada definisi kelas LumbungPadi , terdapat argumen jdm pada method
setJumlahDimasukkan, kemudian pada blok kode method tersebut terdapat instanstiasi obyek
pesan, diikuti dengan deklarasi dan inisialisasi variabel kondisi. Karena variabel-variabel jdm, pesan,
dan kondisi merupakan variabel lokal milik method setJumlahDimasukkan, maka variabelvariabel tersebut ditempatkan pada scope pada stack memory yang diberi nama
setJumlahDimasukkan.
114
12.7 Konstruktor
Konstruktor adalah struktur yang mirip dengan method ( tetapi bukan method ), yang digunakan untuk
melakukan instanstiasi obyek. Ketika dipanggil, Konstruktor akan melakukan inisialisasi nilai variabelvariabel anggota / atribut dari obyek yang akan diinstanstiasi.
keterangan :
a.
b.
c.
d.
[modifiers] merepresentasikan kata kunci teknologi Java yang memodifikasi aksesibilitas terhadap
konstruktor. Contoh : public, protected, atau private.
ConstructorName adalah nama konstruktor. ConstructorName harus sama dengan className.
([arguments]),merepresentasikan sebuah daftar variabel yang nilainya dilewatkan / dimasukkan ke
konstruktor. Bagian ini dapat tidak diisi atau dapat pula diisi dengan banyak variabel.
code_block, adalah rangkaian pernyataan yang dibawa oleh konstruktor.
Catatan : Perhatikan bahwa pada pendefinisian konstruktor, tidak digunakan return_type seperti yang
biasa digunakan pada pendefinisian method.
Pendefinisian konstruktor dapat dilihat pada Contoh 12.9.
115
Contoh 12.9
//file : LumbungPadi2.java
public class LumbungPadi2{
private int persediaan;
private int jumlahDiambil;
private int jumlahDimasukkan;
public LumbungPadi2(){
persediaan = 100;
jumlahDiambil = 10;
jumlahDimasukkan = 20;
}
}
Pada Contoh 12.9, terdapat pendefinisian konstruktor LumbungPadi2(). Ketika konstruktor ini
dipanggil, maka terjadi modifikasi terhadap variabel obyek : persediaan=100,
jumlahDiambil=10, dan jumlahDimasukkan=20. Jadi ketika instanstiasi selesai, obyek
LumbungPadi2 telah memiliki nilai awal untuk masing-masing variabel obyeknya.
Contoh 12.10
//file : LumbungPadi2.java
public class LumbungPadi2{
private int persediaan;
private int jumlahDiambil;
private int jumlahDimasukkan;
public LumbungPadi2(){
persediaan = 0;
jumlahDiambil = 0;
jumlahDimasukkan = 0;
}
public LumbungPadi2(int psd ){
persediaan = psd;
jumlahDiambil = 0;
jumlahDimasukkan = 0;
}
public LumbungPadi2(int psd, int jdimasukkan){
persediaan = psd;
jumlahDiambil = 0;
jumlahDimasukkan = jdimasukkan;
}
}
116
LumbungPadi2()
b.
LumbungPadi2(int)
c.
LumbungPadi2(int,int)
Dalam eksekusi program, jika sebuah konstruktor dipanggil, maka blok kode konstruktor bersangkutan
akan dijalankan. Perhatikan Contoh 12.6.
Contoh 12.11
//file : KegiatanPanen2.java
public class KegiatanPanen2{
public static void main (String[] args){
LumbungPadi2 lumbung1 = new LumbungPadi2();
LumbungPadi2 lumbung2 = new LumbungPadi2(100);
LumbungPadi2 lumbung3 = new LumbungPadi2 (10,50);
}
}
Pada Contoh 12.11 diinstanstiasi 3 obyek LumbungPadi2, yaitu lumbung1, lumbung2, dan
lumbung3. Pada instanstiasi lumbung1, konstruktor LumbungPadi2() dipanggil. Menurut
konstruktor pada Contoh 12.11, maka semua variabel instan pada lumbung1 (persediaan,
jumlahDiambil, dan jumlahDimasukkan) bernilai 0.
Sedangkan pada instanstiasi lumbung2, konstruktor LumbungPadi2(int) dipanggil. Sesuai
dengan definisi konstruktor pada Contoh 12.11, maka isi variabel persediaan adalah 100, sedangkan
jumlahDiambil, dan jumlahDimasukkan bernilai 0.
Pada instanstiasi lumbung3, konstruktor LumbungPadi2(int,int) dipanggil. Sesuai dengan
definisi konstruktor pada Contoh 12.6, maka isi variabel persediaan adalah 10, jumlahDiambil
adalah 0, dan jumlahDimasukkan adalah 50. Visualisasi memorynya ditunjukkan pada Gambar 12.2.
117
Ketika pemanggilan konstruktor induk dengan argumen tidak ditemui, maka yang akan dipanggil secara
implisit adalah konstruktor induk yang tidak memiliki argumen. Jika ternyata di kelas induk tidak
ditemui konstruktor tanpa argumen, hal tersebut akan menyebabkan kesalahan kompilasi.
Pemanggilan konstruktor induk dengan cara memanggil super ini dapat menggunakan beberapa
argumen, yang disesuaikan dengan argumen yang ada di dalam konstruktor-konstruktor di kelas
induknya. Hal yang patut diperhatikan adalah pemanggilan super ini harus berada di baris pertama
dari konstruktor anaknya. Perhatikan Contoh 12.2 berikut ini.
Contoh 12.12
public class Employee {
private static final double BASE_SALARY = 15000.00
private String name;
private double salary;
private Date birthDate;
public Employee(String name, double salary, Date DoB) {
this.name = name;
this.salary = salary;
this.birthDate = DoB;
}
public Employee(String name, double salary) {
this(name, salary, null);
}
public Employee(String name, Date DoB) {
this(name, BASE_SALARY, DoB);
}
public Employee(String name) {
this(name, BASE_SALARY);
}
}
maka dapat dipanggil konstruktor di kelas Employee dari kelas Manager yang meng-extends kelas
Employee dengan cara seperti ditunjukkan pada Contoh 12.13 berikut :
Contoh 12.13
118
Pernyataan super atau this harus dituliskan pada baris pertama dari konstruktor. Jika tidak
menuliskan super() atau this() pada baris pertama konstruktor, maka compiler akan
menyisipkan secara otomatis panggilan terhadap super tanpa menggunakan argumen.
Konstruktor lainnya dapat pula memanggil super() atau this()sehingga dapat terjadi pemanggilan
konstruktor secara berantai (constructor chaining). Hal yang harus diperhatikan adalah konstruktor
pada kelas induk akan lebih dulu dieksekusi sebelum konstruktor pada kelas anaknya.
Contoh 12.14
public class Employee {
protected String name = ;
protected double salary;
protected Date birthDate;
public String getDetails() {
return Name: + name + \n +
Salary: + salary;
}
}
public class Manager extends Employee {
protected String department;
public String getDetails() {
return Name: + name + \n+Salary: + salary + \n +
Manager of: + department;
}
}
Secara definitif, kelas Manager mempunya method yang bernama getDetails() karena kelas
Manager mewarisinya dari kelas Employee. Tetapi, kelas Manager memodofikasi (me-override) isi
dari method tersebut.
Ada aturan yang harus diperhatikan dalam me-override method dari kelas induk seperti :
1. Daftar argumen pada method harus sama (jumlah argumen dan tipenya) dengan method yang dioverride;
2. Tipe kembalian method harus sama dengan method yang di-override;
3. access modifier method tidak boleh lebih ketat (restrictive) daripada method yang di-override;
4. method yang meng-override tidak dapat melempar exception di luar exception yang
dideklarasikan pada method yang di-override. Materi tentang exception dibahas pada bab
selanjutnya.
Untuk lebih jelasnya, perhatikan Contoh 12.15 berikut:
119
Contoh 12.15
class Parent {
public void doSomething() {}
}
class Child extends Parent {
private void doSomething() {}
}
public class UseBoth {
public void doOtherThing() {
Parent p1 = new Parent();
Parent p2 = new Child();
p1.doSomething();
p2.doSomething();
}
}
Pada kelas Parent, dideklarasikan method doSomething() dengan access modifier public. Lalu
di kelas Child yang merupakan subclass dari kelas Parent, didekalarasikan method dengan nama,
daftar argumen, dan tipe kembalian yang sama, tetapi dengan access modifier yang lebih ketat
(private). Selanjutnya, dibuatkan obyek Child yang dimasukkan ke dalam variabel bertipe Parent
pada baris ke-12. Di baris ke-15 dipanggil method doSomething() (p2.doSomething()).
Menurut aturan dalam program Java, method doSomething() dari kelas Child lah yang akan
dieksekusi, tetapi method tersebut dideklarasikan private sehingga variabel p2 (yang dideklarasikan
sebagai kelas Parent) tidak dapat mengaksesnya. Kode di atas melanggar aturan dalam semantik
program Java.
12.13 Polymorphism
Polymorphism berarti kemampuan untuk mengambil beberapa bentuk. Dalam konsep pemrograman,
hal tersebut berarti kemampuan dari sebuah variabel dengan tipe tertentu untuk mengacu ke tipe
obyek yang berbeda.
Pada contoh tentang kelas Manager dan Employee di atas, dapat dibuat obyek Manager dan
diisikan ke variabel bertipe Employee. Hal ini dapat dilakukan karena kelas Manager mewarisi semua
atribut dan method dari kelas induknya dan setiap operasi yang dilakukan oleh obyek Employee juga
dapat dilakukan oleh obyek Manager.
Employee employee = new Manager();
employee.name = James;
employee.department = marketing; //illegal
Melalui penggunaan variabel employee ini, dapat diakses atribut dan method yang merupakan bagian
dari kelas Employee (employee.name), tetapi atribut dan method yang menjadi bagian dari kelas
Manager (employee.department) tidak dapat diakses.
Jika dipanggil method e.getDetails() dan m.getDetails(), akan diperoleh perilaku yang
berbeda. Pemanggilan method yang pertama akan memanggil method getDetails milik kelas
Employee sementara pemanggilan method yang kedua akan memanggil method getDetails milik
kelas Manager. Tetapi, bagaimana jika kasus berikut ditemukan :
120
Mirip dengan penggalan kode sebelumnya, dibuat obyek Manager dan memasukkannya ke dalam
variabel bertipe Employee. Lalu dipanggil method getDetails() melalui variabel ini. Method
getDetails() manakah yang akan dipanggil pada saat runtime, method getDetails() milik
kelas Manager atau Employee ? Jawabannya adalah method getDetails() milik kelas Manager.
Hal ini disebut konsep virtual method invocation. Pada konsep ini, method yang akan dipanggil pada
saat runtime akan ditentukan berdasarkan tipe aktual obyeknya. Pada contoh di atas, karena yang
obyek yang dibuat bertipe Manager, pernyataan e.getDetails() tersebut sebenernya memanggil
method getDetails() milik kelas Manager.
Hal ini boleh dilakukan karena seorang Manager adalah seorang Employee.
Dalam contoh di atas, method menerima variabel referensi (e) bertipe Employee. Selanjutnya
digunakan kata kunci instanceof untuk memastikan bahwa obyek yang dimiliki tersebut merupakan
instance dari kelas Manager. Jika hal itu benar, variabel tersebut di-casting ke variabel bertipe
Manager (m). Melalui penggunaan variabel bertipe Manager ini, dapat dipanggil method yang
terdapat di kelas Manager, yaitu method getDepartment(). Jika tidak menggunakan casting, maka
usaha untuk memanggil method e.getDepartment()akan gagal karena compiler tidak dapat
menemukan method getDepartment() di dalam kelas Employee.
121
Contoh 12.16
public class Bank {
private static final double DEFAULT_INTEREST_RATE=3.2;
}
Untuk kasus variabel referensi, jika menandai variabel tersebut dengan final, maka variabel tersebut
tidak dapat merujuk ke obyek lainnya. Tetapi, isi variabel dari obyek tersebut dapat diubah.
Variabel final kosong adalah sebuah variabel final yang tidak diinisialisasi ketika dideklarasikan.
Biasanya variable ini merupakan variabel instance yang nilainya diberikan di dalam konstruktor.
Variabel final kosong yang dideklarasikan sebagai variabel obyek dapat diberi nilai di bagian
manapun di dalam method, tetapi hanya dapat diberi nila satu kali saja. Kode program berikut
menunjukkan penggunaan variabel final dengan nilai awal kosong.
Contoh 12.17
122
Contoh 12.18
public abstract class Animal {
private int numOfFoots;
private Color color;
public abstract void walk();
public abstract void sound();
}
Pada kode program di atas dideklarasikan kelas Animal yang abstrak, di mana di dalamnya
dideklarasikan dua variabel yaitu numOfFoots dan color. Selain itu, juga dideklarasikan dua buah
method, yaitu walk(), dan sound(). Method di dalam kelas Animal tidak didefiniskan
impelementasi method, dengan harapan bahwa obyek turunan hewan yang spesifik, seperti Chicken
dan Cat akan menyediakan implementasinya yang spesifik dengan kondisi masing-masing hewan. Pada
Contoh 12.18 di atas, method abstrak walk() dan sound() dalam kelas Animal diimplementasikan
oleh kelas Chicken dan Cat.
Kelas abstrak dapat terdiri dari satu atau lebih method abstrak seperti Contoh 12.18 di atas. Kelas
abstrak juga boleh tidak memiliki method abstrak sebagaimana ditunjukkan pada contoh program
berikut.
Contoh 12.19
public abstract class Vehicle {
private String type;
public String getType() {
return type;
}
}
123
Kelas Vehicle pada Contoh 12.19 di atas merupakan contoh kelas abstrak yang legal. Apabila ada
satu saja method yang dideklarasikan dalam sebuah kelas sebagai method abstrak, maka kelas tersebut
harus dideklarasikan abstract.
Method abstrak adalah method yang sudah dideklarasikan, tetapi belum diimplementasikan. Sebuah
method ditulis dengan kata kunci abstract ketika kelas turunan (subclass) di bawahnya menyediakan
implementasi method tersebut.
Method abstrak ditandai dengan modifier abstract, tidak memiliki implementasi, dan diakhiri
dengan tanda titik koma ( ; ).
12.16 Interface
Interface mendefinisikan aturan perilaku (protocol of behavior) yang dapat diimplementasikan oleh
kelas manapun. Interface mendefinisikan satu set method tanpa menyediakan implementasinya.
Sebuah kelas yang mengimplementasi sebuah interface terikat kontrak oleh interface tersebut untuk
mengimplementasi semua method yang ada di dalam interface. Dengan kata lain, kelas tersebut terikat
untuk meng-implementasikan perilaku tertentu yang tertulis dalam interface. Secara substansi,
interface merupakan kumpulan dari method abstrak dan konstanta.
Interface memiliki kemiripan dengan kelas abstrak, di mana keduanya memuat method abstrak.
Perbedaan penting antara interface dan kelas abstrak adalah :
a.
Sebuah interface tidak dapat membuat implementasi satu method pun, sementara kelas abstrak
dapat membuat implementasi satu atau lebih method;
b. Sebuah kelas dapat mengimplementasi beberapa interface, tetapi ia hanya dapat meng-extends
satu superclass.
c. Interface bukan merupakan bagian dari hirarki kelas. Dua kelas yang tidak berhubungan dalam jalur
hirarki kelas dapat mengimplementasi interface yang sama.
<<interface>>
Flyer
+ takeOff()
+ land()
+ fly()
Airplane
+ takeOff()
+ land()
+ fly()
124
Contoh 12.20
public interface Flyer {
public void takeOff();
public void land();
public void fly();
}
public class Airplane implements Flyer {
public void takeOff() {
//accelerate until lift-off
//raise landing gear
}
public void land() {
//lower landing gear
//decelerate and lower flaps until touch-down
//apply breaks
}
public void fly() {
//keep those engines running
}
}
Satu interface Flyer dapat diimplementasikan oleh beberapa kelas. Sebagai contoh, pesawat terbang
(Airplane), burung (Bird), dan superman (Superman), semuanya dapat terbang.
<<interface>>
Flyer
+ takeOff()
+ land()
+ fly()
Bird
Airplane
+ takeOff()
+ land()
+ fly()
+
+
+
+
+
takeOff()
land()
fly()
buildNest()
layEggs()
Superman
+
+
+
+
+
takeOff()
land()
fly()
leapBuilding()
stopBullet()
Sebuah kelas Airplane mungkin merupakan subclass dari kelas Vehicle (kendaraan), dan ia dapat
terbang. Kelas Bird merupakan subclass dari kelas Animal (hewan), dan ia pun dapat terbang.
Contoh di atas menggambarkan bagaimana sebuah kelas dapat mewarisi satu kelas tetapi
mengimplementasi beberapa interface sekaligus.
125
<<interface>>
Flyer
<<interface>>
Sailer
+ takeOff()
+ land()
+ fly()
Vehicle
+ dock()
+ cruise()
Airplane
RiverBarge
+ takeOff()
+ land()
+ fly()
+ dock()
+ cruise()
SeaPlane
Helicopter
+ dock()
+ cruise()
Contoh 12.21
public class EnclosingClass {
//more class definition here
public class NestedClass {
//more class definition here
}
}
Kelas bersarang digunakan untuk membuat hubungan antara dua kelas. Ketika mendefinisikan sebuah
kelas di dalam kelas lainnya, hendaknya dipikirikan bahwa keberadaan kelas bersarang tersebut hanya
akan bermakna ketika ia berada di dalam konteks kelas pembungkusnya (enclosing class) dengan kata
lain, untuk memfungsikannya kelas bersarang tersebut bergantung pada kelas pembungkusnya.
Sebagai anggota dari kelas pembungkus, kelas bersarang memiliki satu kelebihan, yaitu dapat
mengakses semua anggota dar kelas pembungkusnya, termasuk anggota yang dideklarasikan
private. Perhatikan Contoh 12.22 berikut ini.
126
Contoh 12.22
public class Outer1 {
private int size;
/*declare a nested class called "Nested"*/
public class Nested {
public void doStuff() {
//the nested class has access to 'size' from Outer
size++;
}
}
public void testTheNested() {
Nested i = new Nested();
i.doStuff();
}
}
Dalam Contoh 12.22 di atas, kelas Outer1 mendeklarasikan atribut bernama size, sebuah kelas
bersarang yang bernama Nested, dan sebuah method yang bernama testTheNested. Di dalam
kelas Nested, dideklarasikan sebuah method yang bernama doStuff. Method ini mempunyai akses
ke kelas Outer1, di mana variabel size di dalam method tersebut (baris ke-8) mengacu ke data
atribut size dalam kelas Outer1 (baris ke-2). Hal ini berarti obyek bersarang (Nested) mempunyai
referensi ke obyek pembungkusnya (Outer1). Berikut visualisasi hal tersebut di memory.
Execution Stack
Heap Memory
Nested
Outer.this
doStuff
testTheNested
this
i
Outer
0
size
this
main
Gambar 12.16 Representasi kelas bersarang di dalam memory untuk Contoh 12.22.
Contoh 12.23 berikut ini menggambarkan cara menginstantiasi obyek dari kelas bersarang yang
dideklarasikan public dari luar kelas pembungkusnya.
Contoh 12.23
public class Outer2 {
private int size;
public class Nested {
public void doStuff() {
size++;
}
}
}
public class TestNested {
public static void main(String[] args) {
Outer2 outer = new Outer2();
Outer2.Nested nested = outer.new Nested();
nested.doStuff();
}
}
127
Pada Contoh 12.23 di atas, obyek kelas Nested diinstansiasi di dalam konteks instance kelas
pembungkusnya, dalam hal ini kelas Outer2 (baris ke-4 dari method main kelas TestNested).
Berikut ini visualisasi hal tersebut di memory.
Execution Stack
Heap Memory
Nested
Outer.this
Outer
this
doStuff
size
nested
main
outer
Gambar 12.17 Representasi kelas bersarang di dalam Memori untuk Contoh 12.23.
Contoh berikut ini menggambarkan identifikasi variabel dengan nama yang sama.
Contoh 12.24
public class Outer3 {
private int size;
public class Nested {
private int size;
public void doStuff(int size) {
size++;
//the local parameter
this.size++; //the Nested object attribute
Outer3.this.size++; //the Outer3 object attribute
}
}
}
Variabel size digunakan dalam tiga konteks, yaitu: sebagai atribut data kelas Outer3, sebagai atribut
data kelas Nested, dan sebagai variabel lokal dari method doStuff. Hal demikian diperbolehkan
dalam bahasa Java, tetapi tidak dianjurkan dalam pemrograman. Berikut ini visualisasi hal tersebut di
memory,
Execution Stack
Heap Memory
Nested
0
size
Outer.this
Outer
size
size
doStuff
this
main
128
Pada Contoh 12.25 berikut, dibuatkan sebuah kelas bersarang dalam lingkup sebuah method.
Contoh 12.25
public class Outer4 {
private int size = 5;
public Object makeTheNested(int localVar) {
final int finalLocalVar = 6;
//declare a class within a method
class Nested {
public String toString() {
return ("nested size=" + size +
//"localVar=" + localVar + //ERROR: ILLEGAL
"finalLocalVar=" + finalLocalVar);
}
}
return new Nested();
}
public static void main(String[] args) {
Outer4 outer = new Outer4();
Object obj = outer.makeTheNested(47);
System.out.println("the object is "+ obj);
}
}
Kelas yang dideklarasikan di dalam method seperti contoh di atas dinamakan kelas lokal (local class).
Konsep penting dari kelas lokal adalah method-method di dalamnya tidak mempunyai akses penuh di
dalam method yang membungkusnya (outer method). Sebagai contoh, misalkan suatu method
membuat obyek kelas bersarang dan mengembalikan obyek tersebut (baris ke-15). Setelah keluar dari
method makeTheNested, variabel lokal yang ada di dalam method makeTheNested pun hilang,
sehingga method di dalam kelas bersarang (seperti method doStuff) tidak dapat mengakses variabel
tersebut pada saat runtime. Oleh karenanya, pesan error compiler akan muncul apabila baris 11
dijalankan. Tetapi, kelas lokal dapat menggunakan variabel lokal yang dideklarasikan final karena
variabel yang demikian tetap ada meskipun suatu method telah dikembalikan.
Kelas bersarang memiliki bebeapa sifat, antara lain :
kelas bersarang dapat dirujuk dengan menggunakan namanya saja (Nested) dari dalam lingkup
kelas pembungkusnya. Di luar lingkup tersebut, harus digunakan nama lengkapnya
(Outer.Nested). Nama dari kelas bersarang harus berbeda dengan nama kelas pembungkusnya;
kelas di dalam method dapat didefinisikan. Kelas yang demikian dinamaka kelas lokal;
kelas lokal dapat mengakses variabel lokal, termasuk argumen dalam method dari method yang
melingkupinya, dengan syarat variabel tersebut dideklarasikan final;
Kelas bersarang dapat dideklarasikan abstract.
Sebuah interface dapat dideklarasikan di dalam interface lainnya. Interface yang demikian dapat
diimplementasi secara biasa oleh sebuah kelas atau oleh kelas bersarang.
Sebuah kelas bersarang dapat mengakses member statik dari kelas pembungkusnya.
Access modifier apa pun dapat digunakan untuk sebuah kelas bersarang (public, protected,
default, dan private), kecuali kelas lokal. Sebagai contoh, kelas bersarang yang dideklarasikan
private hanya dapat diakses di dalam lingkup kelas pembungkusnya, kelas bersarang yang
dideklarasikan protected dapat digunakan oleh subclass, dan seterusnya. Pemberian access
modifier pada kelas bersarang tidak menghalanginya untuk mengakses atribut pada lingkup kelas
pembungkusnya.
Ketika sebuah file java yang memuat kelas pembungkus dan kelas bersarang dikompilasi, maka baik
kelas pembungkus dan kelas bersarang turut dikompilasi. Nama dari kelas bersarang yang telah
terkompilasi adalah OuterClass$NestedClass dengan ekstensi .class.
129
130
13
ARRAY
Array biasanya digunakan untuk mengelompokkan data atau obyek yang memiliki tipe yang sama.
Array memungkinkan untuk mengacu ke sekumpulan obyek dengan nama yang sama.
Dalam bahasa pemrograman Java, Array merupakan sebuah obyek meskipun ia terdiri dari elemen
yang bertipe data primitif. Seperti halnya kelas lain, ketika mendeklarasikan Array belum dibentuk
sebuah obyek Array. Deklarasi Array hanya membuat sebuah referensi yang dapat digunakan untuk
mengacu ke sebuah obyek Array. Besarnya memory yang digunakan oleh elemen-elemen Array
akan dialokasikan secara dinamis dengan menggunakan pernyataan new atau dengan array
initializer.
Contoh deklarasi array di atas, dengan menggunakan kurung persegi setelah nama variabel, merupakan
standar penulisan array dalam C, C++ dan Java. Format demikian agak sulit untuk dibaca. Oleh
karenanya, bahasa Java menggunakan bentuk deklarasi Array alternatif dengan menggunakan kurung
persegi di sebelah kiri seperti dalam contoh berikut :
Char [] s;
Point [] p;
Sebuah deklarasi Array dapat ditulis sebagai pendeklarasian tipe Array di bagian kiri dan nama
variabel di bagian kanan. Kedua bentuk deklarasi Array di atas dapat digunakan, tetapi sebaiknya
konsisten dalam menggunakan satu bentuk saja. Pada deklarasi Array, tidak ditentukan ukuran aktual
dari Array.
Ketika mendeklarasikan Array dengan kurung persegi yang berada di sebelah kiri nama variabel,
kurung siku tersebut berlaku bagi semua variabel yang berada di sebelah kanannya.
131
Penggalan kode di atas mempunyai representasi dalam heap memory sebagai berikut :
Execution stack
Heap memory
char[]
A
B
C
D
createArray
s
this
main
Indeks Array dimulai dengan angka 0. Batasan legal untuk nilai indeks ini adalah dari nol hingga
jumlah elemen Array 1. Apabila program berusaha mengakses Array di luar batas yang legal, maka
akan muncul pesan runtime exception.
Untuk membuat Array dengan elemen obyek, gunakan cara penulisan berikut :
p = new Point[10];
Pada kode di atas, dibuat sebuah Array yang masing-masing elemennya merupakan referensi obyek
yang bertipe Point. Pernyataan tersebut tidak membuat 10 obyek Point. Untuk membuat obyek
Point, gunakan pernyataan berikut :
P[0] = new Point(0, 1);
P[1] = new Point(1, 2);
...
Perhatikan penggalan kode program berikut ini.
132
Heap memory
Point
0
Point[]
1
Point
1
createArray
s
this
X
Y
Point
2
3
main
Cara singkat ini dapat digunakan untuk Array dengan berbagai jenis tipe, seperti dalam contoh
berikut:
MyDate dates[] = {
new MyDate(22, 7, 1964),
new MyDate(1, 1, 2000),
new MyDate(22, 12, 1964),
};
Pada baris pertama, dibuat sebuah obyek Array yang memiliki empat elemen. Masing-masing elemen
merupakan referensi yang bertipe Array dari int yang bernilai null. Pada baris berikutnya,
diinisialisasi elemen pertama dan kedua dengan obyek Array dari int yang masing-masing berisi lima
elemen yang bertipe integer.
133
Array dari Array yang bersifat non-rectangular dapat dibuat seperti dalam contoh berikut :
twoDim[0]
twoDim[1]
twoDim[2]
twoDim[3]
=
=
=
=
new
new
new
new
int[2];
int[4];
int[6];
int[8];
Proses pembuatan Array dari Array yang demikian, di mana harus diinsialisasi masing-masing
elemennya satu persatu, cukup merepotkan. Di samping itu, Array dari Array yang berbentuk
rectangular lebih sering digunakan dibandingkan dengan yang non- rectangular. Untuk membuat Array
dari Array yang rectangular dengan cara mudah, gunakan bentuk berikut ini :
int twoDim[][] = new int[4][5];
Kode di atas membuat sebuah Array dari empat Array yang setiap elemennya berisi lima nilai int.
Dengan menggunakan atribut length, pemeliharaan kode program menjadi mudah karena program
tidak perlu mengetahui jumlah eleman Array pada saat kompilasi.
Dalam kode program ini, obyek Array yang pertama akan hilang kecuali ada variabel lain yang dibuat
untuk merujuk ke obyek Array tersebut.
Bahasa Java menyediakan method khusus untuk menyalin Array, yaitu dengan menggunakan method
arrayCopy() dari kelas System seperti dalam contoh berikut :
// array semula
int myArray[] = {1, 2, 3, 4, 5, 6};
// array engan elemen yang lebih banyak
int hold[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
//menyalin semua elemen myArray ke hold
// dimulai dengan indeks ke 0
System.arraycopy(myArray, 0, hold, 0,myArray.length);
Setelah proses pengkopian di atas, maka isi dari Array hold adalah 1, 2, 3, 4, 5, 6, 4, 3, 2, 1.
134
14
PENANGANAN EXCEPTION
Exception merupakan sebuah mekanisme yang digunakan oleh bahasa pemrograman komputer untuk
mendeskripsikan apa yang harus dilakukan ketika sesuatu yang tidak dikehendaki terjadi. Sesuatu yang
tidak dikehendaki ini biasanya dalam bentuk error, seperti pemanggilan method dengan arguman yang
tidak valid, kegagalan koneksi dalam sebuah jaringan, atau usaha untuk membuka sebuah file yang
tidak ada.
135
Contoh 14.1
public class HelloWorld {
public static void main(String[] args) {
int i = 0;
String greetings[] = {
"Hello world!",
"No, I mean it!",
"HELLO WORLD!"
};
while(i < 4) {
System.out.println(greetings[i]);
i++;
}
}
}
Jika kode di atas tidak menangani exception, maka program akan berhenti dengan sebuah pesan
kesalahan.
java HelloWorld
Hello world!
No, I mean it!
HELLO WORLD!
java.Lang.ArrayIndexOutOfBoundsException:
at HelloWorld.main(HelloWorld.java:12)
Bahasa pemrograman Java menyediakan mekanisme untuk mengetahui exception apa yang terjadi dan
bagaimana menanganinya.
Mekanisme exception handling memungkinkan program untuk menangkap exception, menanganinya,
dan meneruskan jalannya program. Struktur exception handling dibuat sedemikian rupa sehingga error
dalam program tidak menghalangi jalannya alur normal program. Ketika sebuah error terjadi, ia
ditangani dalam blok kode yang terpisah yang diasosiasikan dengan kode eksekusi program yang
normal. Hal tersebut akan mempermudah pengaturan kode program.
14.4.1
Untuk menangani suatu exception, tempatkan kode di dalam blok try dan membuat satu atau lebih
blok catch, di mana masing-masing blok catch diasosiasikan dengan satu jenis exception yang
mungkin dilemparkan. Pernyataan di dalam blok catch akan dijalankan jika exception yang terjadi
sesuai dengan salah satu exception yang ditangkap oleh salah satu blok catch dalam program. Dalam
sintaksnya, setelah sebuah blok try, dapat ditulis beberapa blok catch, seperti dalam contoh berikut:
try {
//code that might throw a particular exception
} catch(myExceptionType myExcept) {
//code to execute if a MyExceptionType exception is thrown
} catch(Exception otherExcept) {
//code to execute if a general Exception exception is thrown
}
136
14.4.2
Jika sebuah pernyataan melemparkan sebuah exception, dan exception ini tidak ditangani di dalam
method yang melingkupinya, maka exception tersebut akan dilemparkan ke method yang
memanggilnya. Jika exception ini juga tidak ditangani di dalam method pemanggil, maka exception ini
akan dilemparkan ke method pemanggil yang memanggil method ini. Demikian seterusnya. Jika
exception tidak juga ditangani ketika ia mencapai method main(), maka program akan berhenti
dengan tidak normal. Perhatikan kode program berikut ini.
Contoh 14.2
public class MyClass {
public static void main(String[] args) {
first();
second();
}
public static void first() {}
public static void second() {
//exception happens here
}
}
Pada kasus Contoh 14.2 di atas, method main() memanggil sebuah method yang bernama first(),
dan method ini memanggil method lain yang bernama second(). Jika exception terjadi di dalam
method second() dan method second() tidak menangani exception ini, maka exception akan
dilempar ke dalam method first(). Misalkan di dalam method first() terdapat blok catch()
yang menangani exception ini, maka exception tersebut tidak dilemparkan lagi ke method pemanggil
berikutnya. Namun, jika method first() tidak mempunyai block catch() yang sesuai, maka
method berikutnya, yaitu main() akan dicek. Jika method main() juga tidak menangani exception
ini, maka exception tersebut akan dicetak ke dalam output standar dan program berhenti bejalan.
14.6.1
Ketika exception dilemparkan, alur program dalam suatu method membuat jalur yang cenderung tidak
linier, melompati baris-baris tertentu, bahkan mungkin akan keluar sebelum waktunya pada kasus di
mana tidak ada blok catch yang cocok. Kadang-kadang perlu dipastikan bahwa bagian program yang
diberikan akan berjalan, tidak peduli exception apa yang terjadi dan yang ditangkap. Kata kunci
finally dapat digunakan untuk menentukan bagian program seperti itu. Bahkan jika tidak ditemukan
bagian catch yang cocok, bagian finally akan tetap dieksekusi. Setiap pernyataan try
membutuhkan sekurangnya satu bagian catch atau finallly yang cocok. Setiap kali suatu method
akan kembali ke pemanggilnya, melalui exception yang tidak di-catch, atau melalui pernyataan
return, bagian finally pasti dieksekusi. Ini sangat praktis untuk menutup penanganan file dan
membebaskan sejumlah sumber daya lainnya yang mungkin telah dialokasikan di awal program. Berikut
ini merupakan contoh program yang menunjukkan beberapa method yang keluar dengan berbagai cara,
dan semuanya mengeksekusi bagian finally.
Contoh 14.3
public class TryFinally {
static void methodA() {
try {
System.out.println("inside methodA");
throw new RuntimeException();
}finally {
System.out.println("inside finally methodA");
}
}
137
Pada contoh ini, methodA keluar dari blok try dengan melemparkan suatu exception, lalu bagian
finally dieksekusi saat keluar. Mirip dengan hal tersebut, pernyataan try pada methodB keluar
melalui pernyataan return, lalu bagian finally dieksekusi sebelum methodB keluar. Berikut ini
merupakan output dari program ketika dijalankan.
inside
inside
inside
inside
14.7
methodA
finally methodA
methodB
finally methodB
Kategori Exception
Pada bagian sebelumnya, telah dibahas tiga kategori besar exception. Pada gambar berikut ini
ditunjukkan hirarki kelas yang ada di dalam kelas-kelas yang tergabung dalam exception.
Kelas java.lang.Throwable merupakan kelas induk dari semua obyek yang dapat dilemparkan
dan di-catch menggunakan mekanisme penanganan exception. Method-method yang terdapat di dalam
kelas Throwable mengambil pesan kesalahan yang berkaitan dengan satu exception dan mencetak
stack trace untuk menunjukkan di mana exception terjadi. Ada tiga subclass penting dari kelas
Throwable, yaitu kelas Error, RuntimeException, dan Exception.
138
Sebaiknya kelas Throwable tidak digunakan, melainkan menggunakan subclass dari exception untuk
mendeskripsikan satu exception tertentu. Berikut ini ditunjukkan penggunaan dari masing-masing kelas
dalam exception :
Error. Mengindikasikan problem yang fatal yang sulit ditangani. Contoh: out of memory. Program
tidak perlu menangani kondisi yang demikian.
RuntimeException. Exception ini mengindikasikan kondisi yang seharusnya tidak terjadi jika
program berjalan dengan normal. Exception ArrayIndexOutOfBoundsException sebagai
contoh tidak akan terjadi jika Array dengan indeks yang tidak melebihi batas Array tersebut
diakses. Hal yang sama juga berlaku ketika merujuk sebuah variabel obyek yang bernilai null.
Exception yang demikian dapat juga tidak ditangani mengingat program yang didisain dan
diimplementasi secara benar tidak pernah menghasilkan exception tersebut.
Exception yang lain mengindikasikan permasalahan yang muncul pada saat runtime yang
biasanya disebabkan oleh hal-hal yang berkaitan dengan lingkungan di mana program berjalan dan
exception jenis ini dapat ditangani. Contoh yang termasuk ke dalam kategori exception ini adalah
exception karena file yang tidak dapat ditemukan atau URL yang tidak valid, dua hal yang biasanya
dapat terjadi karena pengguna salah ketik.
14.8
Date d = null;
System.out.println(d.toString());
NegativeArraySizeException terjadi ketika program membuat Array dengan indeks
negatif.
ArrayIndexOutOfBoundsException terjadi ketika program mengakses elemen Array
melebihi ukuran Array yang bersangkutan.
SecurityException biasanya dilemparkan di dalam browser, kelas SecurityManager
melemparkan exception ketika sebuah applet berusaha melakukan satu operasi yang
membahayakakn host atau file-filenya. Berikut ini adalah beberapa contoh hal yang dapat
mengakibatkan exception security :
- Mengakses sistem file lokal.
- Membuka soket pada host yang berlainan dengan host yang melayani applet.
14.9
Untuk memastikan penulisan kode program yang baik, bahasa Java menetapkan bahwa jika sebuah
checked exception (yaitu subclass dari kelas Exception tetapi bukan merupakan subclass dari kelas
RuntimeException) terjadi di dalam kode program, maka method tempat terjadinya exception
harus mendefinisikan secara eksplisit tindakan apa yang harus diambil jika exception muncul. Berikut
hal yang harus diperhatikan :
139
a.
Tulis blok try {} dan catch(){} di sekitar kode yang kemungkinan besar akan menghasilkan
exception. Blok catch(){} harus memuat nama exception yang sesuai dengan exception yang
terjadi atau superclass dari exception bersangkutan. Dengan melakukan hal tersebut, exception
sudah ditangani meskipun blok catch(){} dibiarkan kosong;
b. Membuat method tempat exception terjadi. Dengan cara demikian, exception akan dilemparkan ke
method pemanggil.
Sebuah method dapat mendeklarasikan sebuah exception dengan menggunakan kata kunci throws
sebagai berikut:
void trouble() throws IOException {}
Kata kunci throws di atas diikuti oleh daftar semua exception yang akan dilempar ke method
pemanggil. Dalam contoh di atas, hanya dideklarasikan satu exception. Pada method juga dapat
dideklarasikan lebih dari satu exception dengan memisahkan antara satu exception dengan exception
yang lain dengan tanda koma sebagaimana ditunjukkan berikut ini :
void trouble() throws IOException, OtherException {}
Pilihan untuk menangani atau mendeklarasikan exception yang terjadi tergantung dari programmer
dengan mempertimbangkan mana yang lebih layak untuk menangani exception tersebut.
Kelas TestB1 akan berhasil dikompilasi karena EOFException merupakan subclass dari
IOException. Tetapi kelas TestB2 tidak berhasil dikompilasi karena Exception merupakan
superclass dari IOException.
140
15
15.10
MULTITHREADING
Konsep Dasar
Perkembangan sistem komputer dewasa ini menuntut kinerja komputer yang lebih baik. Salah satu
parameter kinerja tersebut misalnya apakah komputer dapat melakukan banyak proses / tugas dalam
waktu yang relatif hampir bersamaan ? Sebuah PC dapat melakukan proses memutar lagu ber-format
MP3, melakukan download file dari server lain, dan mengirim data ke printer untuk dicetak dalam
waktu bersamaan. Karena dukungan spesifikasi mikroprosesor berkecepatan tinggi, maka proses-proses
tersebut dirasakan oleh pengguna dilakukan pada waktu bersamaan, meskipun pada batasan tertentu
eksekusi setiap aplikasi akan terasa tidak serentak dengan eksekusi aplikasi lainnya.
Setiap sistem komputer mempunyai unit pemroses pusat (Central Processing Unit - CPU). CPU akan
menjalankan rangkaian instruksi yang membentuk suatu fungsi tertentu yang mendukung operasional
sistem komputer secara keseluruhan. Sebagai contoh, sebuah CPU dapat menjalankan rangkaian
instruksi untuk memutar piringan hard-disk, menjalankan aplikasi game, mengendalikan peripheral
seperti printer, scanner, bahkan melakukan komunikasi dengan CPU lain pada sistem komputer yang
sama misalnya pada sistem dual-core.
Ketika menjalankan setiap instruksi, CPU selalu menyediakan satu alokasi waktu atau slot waktu. Jadi,
secara low-level setiap instruksi dijalankan pada waktu yang berbeda.
Execution context adalah satu entitas yang menggambarkan satu aliran proses. Execution context dapat
juga disebut sebagai virtual CPU. Artinya, pada sebuah execution context, sebuah proses yang mirip
dengan proses yang dijalankan oleh sebuah CPU secara fisik dijalankan.
Meskipun secara fisik CPU pada sebuah komputer hanya berjumlah 1 atau 2 buah (dual-core), tetapi
dengan menerapkan konsep execution context, satu CPU dapat berjalan lebih dari 1 virtual CPU.
15.11
Membuat Thread
Sebuah thread menggambarkan sebuah execution context. Ketika sebuah thread diinstantiasi, thread
tersebut membutuhkan kode untuk dieksekusi, karena pada dasarnya, thread merupakan suatu entitas
yang mengakomodasi eksekusi program. Kode yang dibutuhkan oleh thread tersebut berada dalam
obyek. Oleh karena itu, pada implementasinya sebuah thread pasti berkorespondensi dengan sebuah
obyek.
Obyek yang datanya akan digunakan dalam thread disebut obyek Thread. Obyek Thread adalah
obyek yang merupakan instanstiasi dari kelas yang merupakan turunan dari kelas Thread, atau
mengimplementasi interface Runnable.
141
Contoh 15.1
public class
private
private
private
private
Pada Contoh 15.1 di atas ditunjukkan kelas Orang yang didefinisikan sebagai turunan dari kelas
Thread. Perhatikan method run() pada kelas Orang. Method ini merupakan overriding method
milik kelas Thread. Ketika thread dijalankan, method run() pada obyek Orang akan dijalankan.
142
Contoh 15.2
public class
private
private
private
private
15.12
Thread merupakan obyek yang menangani eksekusi sebuah proses atau dengan kata lain Thread
adalah representasi sebuah virtual CPU. Oleh karena itu, sebelum proses yang ditangani dieksekusi
terlebih dahulu harus dilakukan deklarasi dan inisialisasi obyek Thread.
Deklarasi dan inisialisasi obyek Thread dapat dilakukan tergantung cara pendefinisian kelasnya,
apakah mengimplementasi interface Runnable atau menurunkan dari kelas Thread.
Untuk thread yang obyeknya diturunkan langsung dari kelas Thread, deklarasi dan inisialisasinya
dapat langsung dilakukan dengan memanggil konstruktornya saja. Dengan demikian obyek dan threadnya sudah langsung terbentuk. Deklarasi dan inisialisasi obyek Thread dengan cara ini diperlihatkan
pada contoh kode program berikut.
Contoh 15.3
Untuk thread yang obyeknya mengimplementasi interface Runnable, dapat digunakan konstruktorkonstruktor sebagai berikut :
a. Thread(Runnable t)
b. Thread(Runnable t, String name).
dengan obyek yang mengimplementasi interface Runnable menjadi argumen dari konstruktor
tersebut. Deklarasi dan inisialisasi obyek Thread dengan cara tersebut ditunjukkan pada contoh kode
program berikut ini.
143
Contoh 15.4
15.13
Menjalankan Thread
Sebelum masuk pada pembahasan eksekusi thread, terlebih dahulu dibahas mengenai status minimal
pada thread. Status ini menggambarkan keadaan thread pada saat dieksekusi.
Ketika sebuah thread mulai dijalankan, maka thread tersebut akan masuk ke dalam status yang disebut
Runnable. Pada saat thread masuk status ini, maka pada saat itu juga thread itu masuk ke dalam
daftar scheduler yang kemudian menunggu untuk dieksekusi. Keputusan sebuah thread dieksekusi atau
tidak bergantung pada scheduler. Scheduler akan mengatur penggiliran eksekusi.
Thread yang mendapat kesempatan untuk dieksekusi, akan masuk ke dalam status Running. Pada
status ini, jika tidak ada interupsi atau penundaan eksekusi, thread akan dieksekusi sampai pada akhir
pernyataannya.
Thread yang dieksekusi tanpa interupsi atau penundaan ketika proses yang dibawanya selesai
dieksekusi akan masuk ke dalam akhir dari sikulus hidup thread, yaitu Dead.
Jika pada saat menjalankan eksekusi, suatu thread terkena interupsi atau penundaan, maka thread
tersebut masuk ke dalam status Blocked. Pada status ini, thread akan menunggu sampai dirinya
memenuhi syarat untuk bisa masuk lagi ke status Runnable. Misalnya jika thread tersebut masuk
status Blocked karena penundaan eksekusi, maka kesempatan untuk masuk ke status Runnable
akan didapatkan ketika waktu penundaannya sudah selesai. Untuk lebih jelasnya, perhatikan gambar
berikut ini.
144
Contoh 15.5
Sedangkan untuk thread yang obyeknya merupakan implementasi interface Runnable, cara
memulainya adalah dengan memanggil method start()milik Thread. Contoh kode program berikut
menunjukkan cara pemanggilan method start() milik Thread.
Contoh 15.6
public class AplikasiThread1 {
public static void main(String[] args){
Orang rudi = new Orang("Rudi", "Medan", 1000L);
Thread t1 = new Thread(rudi);
t1.start();
}
}
Ketika method start() dipanggil, blok kode pada method run() akan dijalankan. Proses thread
dapat ditunda selama sekian milidetik dengan pemanggilan method berikut.
Thread.sleep(delay);
15.13.2 Multithreading
Dalam satu aplikasi dapat dibuat lebih dari satu thread. Fitur ini dinamakan multithreading. Pada
multithreading, thread-thread akan dijalankan seakan-akan bersamaan. Mengapa seakan-akan ?
Karena sebenarnya jika diamati pada low level, sebenarnya thread-thread tersebut tidak berjalan
bersamaan, tetapi karena selisih waktu antara eksekusi thread yang satu dengan yang lain terlalu kecil,
maka seakan-akan eksekusi thread-thread dirasakan bersamaan oleh manusia. Perhatikan contoh kode
program berikut ini.
Contoh 15.6
public class AplikasiThread1 {
public static void main(String[] args){
Orang rudi = new Orang("Rudi", "Medan", 5L);
Orang stefani = new Orang("Stefani","Bandung",3L);
Orang ahmad = new Orang("Ahmad", "Jakarta",2L);
Thread t1 = new Thread(rudi);
Thread t2 = new Thread (stefani);
Thread t3 = new Thread(ahmad);
t1.start();
t2.start();
t3.start();
}
}
Pada Contoh 15.6 di atas diperlihatkan 3 buah obyek Orang : rudi, stefani, dan ahmad yang
mempunyai method run() untuk dieksekusi oleh thread. Ketiga obyek tersebut akan dienkapsulasi ke
dalam obyek-obyek Thread t1, t2, dan t3. Setelah obyek-obyek t1, t2, dan t3 selesai diinstanstiasi,
maka langkah berikutnya adalah menjalankan thread-thread tersebut dengan memanggil method
start() pada masing-masing thread.
145
Ketika pemanggilan method start(), obyek-obyek t1, t2, dan t3 masuk ke status Runnable dan
menunggu scheduler untuk dieksekusi dalam hal ini dimasukkan ke dalam status Running.
Gambar 15.2 memperlihatkan penggiliran eksekusi di antara dua Thread. Perlu ditegaskan bahwa
pada suatu saat hanya ada satu thread yang memiliki status Running. Ketika pada suatu saat tidak
ada thread yang masuk ke status Running, maka thread lain yang sedang berada pada status
Runnable akan segera diubah statusnya menjadi Running oleh scheduler.
Pada Gambar 15.2 juga diperlihatkan bahwa ketika Thread 1 mengalami penundaan (delay) atau
statusnya berubah menjadi Blocked, Thread 2 akan berstatus Running. Ketika Thread 2 masuk ke
status penundaah, Thread 1 akan masuk ke dalam status Running.
15.14
Method-method Thread
Berikut ini daftar-daftar method penting lainnya yang dapat digunakan dalam mengeksekusi suatu
Thread :
a.
sleep()
Method ini akan menghentikan proses pada sebuah thread selama beberapa milidetik. Thread
mempunyai 2 buah method sleep dengan argumen-argumen berikut :
-
Seperti telah dijelaskan, sleep() menyebabkan sebuah thread masuk ke dalam status Blocked.
Sebagai catatann bahwa method sleep() ini merupakan method statik dan penggunaannya
harus berada dalam blok try...catch dengan exception handler berupa
InterruptedException atau superclass-nya.
b.
join()
c.
Method ini akan mengakibatkan method pemanggil akan menunggu sampai Thread yang method
join()-nya dipanggil masuk ke dalam status Dead.
currentThread()
Method ini merupakan method statik yang menghasilkan obyek Thread yang sedang berjalan.
146
d.
yield()
Method statik ini menyebabkan runtime mengalihkan konteks dari thread yang sedang berjalan ke
thread lain yang tersedia yang siap dijalankan. Penggunaan method ini merupakan suatu cara untuk
memastikan bahwa thread dengan prioritas lebih rendah tidak memaksakan untuk berjalan.
e.
stop()
Method ini menyebabkan thread segera berhenti. Ini sering dijadikan cara tercepat untuk
mengakhiri suatu thread khususnya jika method ini dieksekusi pada thread yang berlaku. Pada
kasus ini, baris program setelah pemanggilan method stop() tidak pernah dieksekusi karena
konteks jalinan musnah sebelum stop() selesai.
f.
suspend()
Method suspend() berbeda dengan stop(). Method ini mengambil thread tertentu dan
menyebabkannya berhenti tanpa menghancurkan thread di bawahnya atau keadaan thread yang
berjalan sebelumnya. Jika suatu thread di-suspend, panggil method resume() pada thread yang
sama untuk menjalankannya lagi.
g.
resume()
Method ini digunakan untuk menghidupkan method yang di-suspend. Tidak ada jaminan bahwa
thread yang dijalankan kembali akan berjalan dengan baik karena mungkin sudah ada thread
dengan prioritas lebih tinggi yang berjalan. Tetapi, resume() memungkinkan thread untuk
berjalan kembali.
h.
setPriority()
Method ini mengisi prioritas suatu thread dengan beseran integer yang dimasukkan. Ada sejumlah
konstanta prioritas yang telah ditetapkan dalam kelas Thread, yaitu MIN_PRIORITY,
NORM_PRIORITY, dan MAX_PRIORITY yang secara berurut bernilai 1, 5, dan 10.
i.
getPriority()
Method ini menghasilkan prioritas thread saat itu berupa suatu nilai antara 1 dan 10.
15.15
Sinkronisasi Thread
Beberapa thread dalam suatu aplikasi dapat mengakses atribut pada satu obyek yang sama. Dan
seringkali dalam perancangan atribut pada obyek yang sama atau obyek yang di-share tersebut
memiliki aturan dalam penentuan nilainya. Sebagai contoh, pada aplikasi sebuah sistem pemesanan
tiket kereta api yang kita sebut saja Ticket Box. Ada dua atribut yang penentuan nilainya memiliki
aturan, yaitu :
a. Persediaan tiket dengan aturan :
- nilainya tidak boleh lebih rendah dari 0;
- nilainya tidak boleh lebih tinggi dari kapasitas maksimum kursi;
- jika nilainya mencapai kapasitas maksimum kursi (belum ada tiket yang dipesan), maka proses
pembatalan tidak akan menghasilkan pembaharuan nilai;
- jika nilainya berada pada angka 0 (semua tiket terbeli), maka proses pemesanan tidak akan
menghasilkan pembaharuan nilai.
b. Pendapatan yang dihasilkan dari penjualan tiket dengan aturan :
- nilainya tidak boleh lebih rendah dari 0;
- jika petugas loket melakukan proses pemesanan dan nilai persediaan tiket terbaharui, maka
nilai pendapatan harus ditambah sejumlah harga satuan yang ditetapkan;
- jika petugas loket melakukan proses pembatalan dan nilai persediaan tiket terbaharui, maka nilai
pendapatan harus dikurangi sejumlah harga satuan atau jumlah uang yang dikembalikan;
- Jika tidak terjadi pembaharuan nilai persediaan tiket, maka tidak terjadi juga pembaharuan nilai
pendapatan.
147
Misalnya pada sebuah pusat reservasi tiket, terdapat 3 loket, yaitu Loket 1, Loket 2, dan Loket 3. Jika
seorang petugas di Loket 1 akan melakukan proses pemesanan/pembatalan, maka langkah yang
dilakukan adalah (jika semua persyaratan terpenuhi untuk pembaharuan) :
1. Memperbaharui nilai persediaan :
jika prosesnya adalah pemesanan :
jika persediaan > 0 :
persediaan = persediaan - 1
memperbaharui pendapatan diizinkan.
Jika persediaan <=0 :
tidak dilakukan updating persediaan
memperbaharui pendapatan tidak diizinkan.
jika prosesnya adalah pembatalan :
jika persediaan < jumlah tiket maksimum :
persediaan = persediaan + 1
memperbaharui pendapatan diizinkan
jika persediaan >= jumlah tiket maksimum :
tidak dilakukan updating persediaan
memperbaharui pendapatan tidak diizinkan.
Sebuah proses pemesanan / pembatalan akan dikatakan sebagai proses yang lengkap, apabila kedua
langkah tersebut telah selesai dilaksanakan.
Jika program bekerja dalam single thread (misalnya hanya terdapat 1 loket saja), maka hal ini tidak
menimbulkan masalah. Masalah akan muncul ketika program bekerja dalam multiple thread ( dengan
menggunakan lebih dari 1 loket yang berjalan paralel). Dengan asumsi semua loket mengakses ticket
box yang sama, maka dapat terjadi kejadian berikut : ketika loket 1 baru saja melakukan pembaharuan
persediaan tiket (langkah 1), loket 2 masuk ke langkah 1 dan melakukan pembaharuan persediaan tiket.
Gambar 15.3 menunjukkan proses yang terjadi pada dua buat loket yang diposisikan sebagai Thread.
Pada awal proses, Loket 1 lebih dulu melakukan proses (masuk ke status Running), sedangkan Loket
2, yang mulai lebih lambat daripada Loket 1, harus menunggu (masuk ke status Runnable), sampai
Loket 1 masuk ke fase menunggu ( masuk ke status Blocked).
148
Ketika Loket 1 melakukan proses, Loket 1 menetapkan bahwa prosesnya adalah PEMESANAN. Oleh
karena itu, Loket 1 melakukan pemeriksaan jumlah persediaan tiket. Karena persediaan tiket = 100,
yang berarti masih dapat dipesan, maka Loket 1 melakukan aksi, yaitu pengurangan jumlah persediaan
dengan 1. Persediaan tiket menjadi 99.Tetapi, ketika proses pada Loket 1 belum selesai ( Loket 1 belum
melakukan pembaharuan pendapatan), proses berpindah ke Loket 2, yang melakukan proses
PEMESANAN. Loket 2 akan melakukan pemeriksaan jumlah persediaan. Karena jumlah persediaan
adalah 99, maka proses pemesanan dapat dilakukan. Loket 2 akan melakukan aksi, berupa pengurangan
jumlah persediaan menjadi 98 dan menyatakan bahwa pembaharuan pendapatan diizinkan. Pada
Gambar 15.3 diasumsikan Loket 1 masih berada pada status Blocked sehingga Loket 2 masih dapat
melakukan prosesnya.
Loket 2 akan melakukan pemeriksaan, apakah pendapatan dapat diperbaharui. Karena pada aksi
sebelumnya telah dinyatakan bahwa pembaharuan pendapatan dapat dilakukan, maka langkah
berikutnya adalah melakukan aksi, yaitu menjumlahkan pendapatan dengan harga satuan, yang
diasumsikan = 160000.
Perhatikan komposisi persediaan-pendapatan yang diberi warna kuning pada Gambar 15.3. Terlihat
suatu ketidak-konsistenan setelah Loket 2 menyelesaikan transaksi. Persediaan tercatat 98, yang berarti
2 tiket telah terjual, tetapi pendapatan yang diterima adalah 160000, yang setara dengan 1 tiket terjual.
Hal ini dikarenakan ketika transaksi pada Loket 1 belum selesai, Loket 2 mendapat giliran melakukan
transaksi. Akibatnya, Loket 2 memulai transaksi dengan kondisi awal persediaan dan pendapatan yang
tidak konsisten. Akhirnya, setelah Loket 2 selesai bertransaksi, hasil akhir persediaan - income juga tidak
konsisten. Untuk mencegah terjadinya ketidak-konsistenan semacam ini, perlu dilakukan sinkronisasi
thread.
Contoh sinkronisasi thread dapat dilihat pada Gambar 15.4. Pada Gambar 15.4 diperlihatkan bahwa
sebelum Loket 1 menyelesaikan transaksinya, Loket 2 akan terus menunggu. Dengan disain seperti ini,
dijamin nilai-nilai pada persediaan dan income akan konsisten.
15.16
Untuk dapat melakukan sinkronisasi thread, teknologi Java memperkenalkan terminologi lock pada
obyek. Lock merupakan kunci virtual yang dimiliki oleh obyek. Kunci virtual ini dapat dimiliki oleh
obyek lain yang mengakses obyek pemilik kunci. Akibatnya adalah : selama obyek A memiliki kunci dari
obyek yang diakses ( misalnya obyek B) , maka obyek C tidak dapat mengakses obyek B. Obyek C akan
terus menunggu sampai obyek A melepaskan kunci obyek B dan obyek B memiliki kembali kunci
tersebut. Untuk lebih jelasnya, perhatikan Gambar 15.5 dan Gambar 15.6.
149
Untuk menghasilkan sinkronisasi di antara thread, maka teknologi Java menyediakan kata kunci
synchronized yang akan menyebabkan lock / kunci obyek berpindah ke thread yang mengakses
obyek tersebut.
Penggunaan kata kunci synchronized menyebabkan diagram status pada model I dimodifikasi
menjadi model II, seperti pada Gambar 15.7.
Pada diagram state model II, terdapat tambahan status, yaitu BLOCKED in objects lock pool. Artinya,
ketika ada thread yang mengakses suatu obyek B yang memiliki method atau blok yang menggunakan
kata kunci synchronized, thread lain harus menunggu untuk mengakses obyek B tersebut. Thread
lain tersebut masuk ke dalam status BLOCKED in objects lock pool.
150
Ketika thread pemegang lock tersebut mengembalikan kunci kepada obyek B, maka thread yang sedang
menunggu di BLOCKED in objects lock pool mendapatkan kunci obyek B, dan masuk ke dalam status
Runnable. Seperti pada Model I, thread pemegang kunci obyek B tersebut dipilih oleh scheduler
untuk masuk ke status Running. Dengan demikian, perilaku yang dihasilkan adalah sebagai berikut :
- Ketika sebuah method / blok dari sebuah obyek yang menggunakan kata kunci synchronized
diakses oleh sebuah thread, thread lain tidak dapat mengakses method-method tersinkronisasi milik
obyek tersebut.
- Ketika sebuah method / blok dari sebuah obyek yang menggunakan kata kunci synchronized
diakses oleh sebuah thread, thread lain masih dapat mengakses method-method yang tidak
tersinkronisasi milik obyek tersebut.
Contoh penggunaan kata kunci synchronized pada method adalah sebagai berikut :
Contoh 15.7
class Callme{
synchronized void call(String msg){
System.out.print("[" + msg);
try {
Thread.sleep(1000);
}catch (Exception e){}
System.out.println("]");
}
}
151
Pada Contoh 15.7 di atas terdapat tiga kelas sederhana. Kelas pertama adalah kelas Callme yang
memiliki method tunggal bernama call(String msg). Method ini memerlukan parameter
String msg. Method ini mencoba mencetak String msg di antara tanda kurung persegi.
Perhatikan bahwa setelah mencetak kurung persegi buka dan string msg, method ini akan
memanggil Thread.sleep(1000) yang menghentikan thread yang sedang berjalan selama satu
detik.
Kelas kedua adalah kelas Caller. Kelas ini memiliki konstruktor yang memerlukan referensi ke suatu
instance kelas Callme dan suatu String yang secara berurut disimpan dalam variabel target dan
msg. Konstruktor juga membuat suatu Thread baru yang akan memanggil method run() milik obyek
ini. Selanjutnya, thread segera dimulai. Method run() pada Caller memanggil method call milik
obyek target (instance kelas Callme) dengan melewatkan string msg.
Akhirnya, kelas Shyncronizer membuat instance tunggal dari kelas Callme dan tiga instan kelas
Caller masing-masing dengan String pesan yang berbeda. Instance kelas Callme yang sama
dilewatkan pada setiap Caller. Keluaran dari program di atas adalah sebagai berikut :
EKSPERIMEN
Apa yang akan terjadi, jika method call milik kelas Callme tidak disertakan kata kunci
synchronized ? Jelaskan alasannya !
Contoh penggunaan kata kunci syncronized pada satu blok baris program pada method adalah
sebagai berikut :
152
Pada contoh di atas, ketika sebuah Thread I memanggil method batal(), Thread II masih
punya kesempatan untuk mengakses method batal() bersamaan dengan Thread I. Tetapi ketika
Thread I mengakses blok synchronized, maka ketika Thread II selesai memeriksa kondisi
persediaan < MAX, Thread II akan menunggu sampai Thread I selesai mengeksekusi barisbaris program pada blok synchronized.
Perhatikan bahwa blok synchronized menggunakan argumen sebuah obyek. Artinya, ketika sebuah
thread mengakses blok synchronized, maka thread lain tidak dapat mengakses method-method /
baris-baris program tersinkronisasi pada obyek yang menjadi argumen synchronized.
15.17
Sebuah thread dapat melakukan komunikasi dengan thread lainnya. Komunikasi tersebut berkaitan
dengan penggiliran pemakaian kunci obyek. Ketika sebuah thread selesai mengakses sebuah method /
blok tersinkronisasi dari sebuah thread, obyek tersebut akan mengembalikan kunci ke obyek pemiliknya
Secara otomatis ketika sebuah kunci obyek dikembalikan ke obyek bersangkutan, salah satu dari
thread-thread yang menunggu giliran mendapatkan kunci obyek akan mendapatkan kunci tersebut dan
masuk ke dalam status Runnable. Inilah disebut komunikasi antar thread.
Komunikasi antar thread dapat dibuat tidak otomatis, yaitu dengan menggunakan method wait() ,
notify(), dan notifyAll() milik obyek yang kuncinya dipegang oleh thread. Dengan penggunaan
ketiga method tersebut, model diagram status pada thread berkembang menjadi model III seperti pada
Gambar 15.8.
Pada diagram state model III, terdapat satu tambahan status, yaitu BLOCKED in objects wait pool.
Status ini merupakan status untuk obyek-obyek yang menunggu kunci obyek dengan cara memanggil
method wait().
Method wait() menyebabkan thread terakhir yang mengakses obyek melepaskan kunci obyek dan
menunggu sampai thread lain yang mengambil kunci obyek tersebut melepaskannya kembali ke obyek.
Terdapat 2 jenis method wait(), yaitu :
153
a. wait() menunggu sampai waktu tak berhingga sampai ada thread yang menyerahkan kunci obyek
kepada obyek bersangkutan. Jika ada obyek yang menyerahkan kunci obyek kepada obyek
bersangkutan, maka method notify() akan dipanggil dari thread yang berada dalam status
BLOCKED in objects wait pool, sehingga thread pindah ke status BLOCKED in objects lock pool.
b. wait (long timeout) menunggu sampai timeout milidetik. Jika sampai batas waktu
timeout tidak ada obyek yang menyerahkan kunci obyek, maka secara otomatis method
interrupt() dari thread akan dipanggil, dan thread masuk ke dalam status BLOCKED in objects
lock pool.
Sebagai catatan bahwa method wait() hanya dapat dipanggil oleh thread pemegang kunci obyek.
Jika sebuah thread yang tidak memegang kunci obyek memanggil wait(), maka akan terjadi eksepsi,
yaitu IllegalMonitorStateException.
Thread yang berada pada status BLOCKED in objects wait pool tidak dapat menerima kunci obyek,
meskipun kunci obyek telah dikembalikan ke obyek bersangkutan. Untuk dapat menerima kunci obyek,
thread harus pindah ke status BLOCKED in objects lock pool terlebih dahulu dengan menggunakan
notify(), notifyAll() , atau interrupt().
Method notify() akan menyebabkan thread pemegang kunci obyek melepaskan kunci obyek dan
obyek pemilik kunci memilih salah satu thread pada status BLOCKED in objects wait pool untuk diubah
statusnya ke BLOCKED in objects lock pool.
Method notifyAll() akan menyebabkan thread pemegang kunci obyek melepaskan kunci obyek
dan obyek pemilik kunci memindahkan semua thread yang berada pada status BLOCK in objects wait
pool ke status BLOCKED in objects lock pool. Untuk lebih jelasnya, perhatikan kode program berikut .
Contoh 15.8
class Transaction{
int i;
synchronized int get(){
System.out.println("Got : " + i);
return i;
}
synchronized void put(int i){
this.i = i;
System.out.println("Put : " + i);
}
}
class Producer implements Runnable{
Transaction trans;
Producer(Transaction trans){
this.trans = trans;
new Thread(this, "Producer").start();
}
public void run(){
int i = 0;
while(true){
trans.put(i++);
}
}
}
class Customer implements Runnable {
Transaction trans;
Customer(Transaction trans){
this.trans = trans;
new Thread(this, "Customer").start();
}
154
Contoh program di atas terdiri dari empat kelas sederhana, yaitu Transaction, Producer,
Customer, dan TransactionTest. Kelas Transaction mendefinisikan antrian yang aksesnya
ingin disinkronkan. Kelas Producer menghasilkan isi antrian. Kelas Customer menggunakan isi
antrian. Kelas TransactionTest menghasilkan kelas Transaction, Producer, dan Customer
tunggal.
Meskipun method put dan get pada Transaction sudah disinkronkan, masih tidak mungkin
menghentikan produsen supaya tidak mendahului konsumen. Selain itu, juga tidak mungkin
menghentikan konsumen supaya tidak mengkonsumsi nilai antrian yang sama lebih dari satu kali. Jadi,
program di atas akan menghasilkan keluaran yang masih salah seperti berikut ini.
Put
Got
Got
Got
Got
Got
Put
Put
Put
Put
Put
Put
Put
...
:
:
:
:
:
:
:
:
:
:
:
:
:
1
1
1
1
1
1
2
3
4
5
6
7
7
Cara untuk mengatasi masalah di atas adalah dengan menggunakan method wait() dan notify()
untuk memberi isyarat dua arah. Pada Method get terdapat mekanisme untuk menunggu (wait)
sampai Producer memberitahu bahwa sudah ada data yang siap. Setelah Customer memanggil data
tersebut, Customer memberitahu (notify) Producer bahwa sudah boleh menambah data di antrian.
Method put terdapat mekanisme menunggu (wait) sampai Customer sudah menghilangkan data
terakhir yang disimpan di antrian. Lalu, setelah memasukkan data baru, Produser memberitahu
(notify) Customer supaya menghilangkan data baru tersebut. Berikut kelas Transaction yang
sudah dimodifikasi.
Contoh 15.9
class Transaction{
int i;
boolean valueSet = true;
synchronized int get(){
if (!valueSet)
try {
wait();
}catch(InterruptedException e){}
System.out.println("Got :" + i);
155
valueSet = false;
notify();
return i;
}
synchronized void put(int i){
if (valueSet)
try {
wait();
}catch(InterruptedException e){}
this.i = i;
valueSet = true;
System.out.println("Put :" + i);
notify();
}
}
:
:
:
:
:
:
:
:
15.18
1
1
2
2
3
3
4
4
DeadLock
Deadlock biasanya jarang terjadi, tetapi sangat sulit untuk menelusuri keadaan kesalahan di mana dua
jalinan memiliki saling kebergantungan pada sepasang obyek yang disinkronkan. Perhatikan Contoh
15.10. Pada contoh tersebut satu thread memasuki monitor pada obyek X dan thread lain memasuki
monitor pada Obyek Y. Kemudian jika X mencoba memanggil suatu method yang disinkronkan Y, maka
X akan membloknya. Tetapi, jika Y pada gilirannya mencoba memanggil suatu method yang
disinkronkan pada X, maka Y akan menunggu selamanya karena untuk mendapatkan kunci pada X,
pertama kali X harus melepaskan kuncinya kepada Y sehingga thread pertama dapat dilengkapi. Untuk
lebih jelasnya, perhatikan contoh program berikut ini.
Contoh 15.10
class X {
synchronized void foo(Y y){
System.out.println(Thread.currentThread().getName() + " memasuki X.foo");
try{
Thread.sleep(1000);
}catch (Exception e){}
System.out.println(name + " mencoba memanggil Y.last()");
y.last();
}
synchronized void last(){
System.out.println(" Di dalam X.last()");
}
}
class Y {
synchronized void bar(X x){
System.out.println(Thread.currentThread().getName() + " memasuki Y.bar");
try{
Thread.sleep(1000);
}catch (Exception e){}
System.out.println(name + " mencoba memanggil X.last()");
x.last();
}
156
Pada contoh di atas dibuatkan dua kelas, yaitu X dan Y yang secara berurut memiliki method foo dan
bar, yang berhenti sebentar sebelum mencoba memanggil method lain. Kelas utama bernama A
menciptakan instance A dan B, lalu mengambil thread kedua untuk menyiapkan keadaan deadlock.
Method foo dan bar menggunakan sleep untuk memaksa munculnya keadaan deadlock. Teknik
Industri memiliki monitor pada y sambil menunggu monitor pada x. pada saat yang sama Sistem
Informasi memiliki x dan menunggu untuk mengambil y. Program ini tidak akan pernah selesai.
Berikut keluaran dari program di atas.
Teknik
Sistem
Teknik
Sistem
EKSPERIMEN
1.
Buatlah visualisasi yang menggambarkan kondisi deadlock pada Contoh 15.10 seperti halnya
visualisasi yang ditunjukkan pada Gambar 15.4, Gambar 15.5, dan Gambar 15.6 !
2.
Apa yang seharusnya dilakukan untuk menghindari deadlock seperti pada Contoh 15.1 !
157
158
16
16.12 Stream
Untuk memahami Java I/O, perlu dipahami konsep stream. Stream adalah sebuah baris berurut dari
byte-byte data dengan panjang yang tidak tertentu (undeterministic). Perhatikan ilustrasi stream pada
Gambar berikut ini.
Informasi yang dibawa oleh stream merupakan byte-byte urutan kombinasi bit-bit 1 dan 0 dan belum
mengalami interpretasi tertentu, misalnya interpretasi karakter Unicode.
Pada teknologi Java, stream terbagi atas 2 kategori, yaitu :
a. Byte stream, yaitu stream yang membawa informasi berupa byte-byte yang dipresentasikan sebagai
bilangan-bilangan kode ASCII.
b. Character stream, yaitu stream yang membawa informasi berupa byte-byte yang direpresentasikan
sebagai karakter.
159
Proses aliran data pada teknologi Java menggunakan terminologi sumber data dan tujuan data di
mana arah aliran data adalah dari sumber data menuju ke tujuan data. Sumber data (data source)
adalah perangkat/entitas yang menyimpan data yang akan diambil oleh program untuk diproses.
Sedangkan tujuan data (data sink) adalah perangkat/entitas yang berfungsi sebagai tempat
menyimpan/menampilkan data yang telah selesai diproses oleh program.
Konsep sumber data dan tujuan data ini membutuhkan obyek-obyek yang dapat membaca,
menampung, dan menuliskan data. Oleh karena itu teknologi Java memperkenalkan kelas
InputStream, OutputStream, Reader, dan Writer yang masing-masing menangani
pembacaan informasi pada byte stream, penulisan informasi pada byte stream, pembacaan informasi
pada character stream, dan penulisan informasi pada character stream.
Sumber data dan tujuan data lebih umum disebut node stream. Sedangkan aliran data lebih umum
disebut stream saja.
InputStream adalah sebuah kelas abstrak yang merepresentasikan sebuah input stream yang
memuat informasi berupa barisan byte. InputStream akan membaca byte-byte dari sumber data,
misalnya keyboard.
InputStream memiliki beberapa method sebagai berikut :
a.
b.
c.
public int read (byte[] data, int offset, int length) throws
IOException
Method ini membaca beberapa bytes data dan menyimpannya dalam buffer b, dimulai dari
indeks ke-offset sepanjang length.
d.
e.
f.
160
Contoh di atas menunjukkan sebuah program untuk membaca data yang dimasukkan melalui keyboard.
Pada method main(), dideklarasikan obyek dis yang merupakan instance dari kelas
DataInputStream dan variabel primitif hasil bertipe int. Pada blok try...catch obyek dis
diinstanstiasi dengan menggunakan konstruktor DataInputStream(InputStream). Pada kasus
ini argumen yang digunakan sebagai inputstream adalah System.in.
Sebagai catatan, variabel statik in pada kelas System merupakan inputstream standar pada
teknologi Java yang menyimpan data yang dikirimkan melalui keyboard. Dengan demikian, obyek dis
akan membaca semua informasi yang masuk melalui keyboard.
Pada baris ke-9 dilakukan pembacaan data yang dimasukkan melalui keyboard. Program akan
menunggu sampai terjadi penekanan tombol Enter pada keyboard, kemudian data tersebut
dikembalikan ke variabel hasil. Data yang dimasukkan ke hasil adalah kode ASCII dari karakter keyboard
yang dimasukkan.
Jika kita mengetikkan abc pada keyboard, maka output yang dihasilkan oleh program di atas adalah
sebagai berikut :
ASCII
ASCII
ASCII
ASCII
ASCII
=
=
=
=
=
97
98
99
13
10
161
Tabel 16.1
Set Karakter ASCII
Pada baris ke-10 nilai yang disimpan oleh variabel hasil akan dicetak ke layar monitor. Nilai yang dicetak
adalah kode ASCII dari karakter yang bersesuaian. Langkah terakhir adalah menutup input stream dis.
Penutupan stream ini sebaiknya wajib dilakukan karena JVM memiliki kemampuan terbatas untuk
jumlah stream maksimum yang dibuka. Meskipun dalam contoh program di atas tidak terlihat
keterbatasan JVM tersebut, alangkah baiknya jika penutupan stream selalu dilakukan untuk
menghemat resource.
OutputStream adalah sebuah kelas abstrak yang merepresentasikan sebuah output stream yang
akan menjadi tujuan aliran urutan byte. OutputStream akan menampung data yang diberikan
kepadanya dan menuliskannya ke media output yang bersesuaian, misalnya ke layar monitor atau file.
Pada contoh sebelumnya ditunjukkan hasil pembacaan byte yang dicetak ke layar monitor. Variabel
System.out adalah variabel statik yang merupakan instance dari kelas PrintStream, kelas
turunan dari OutputStream. Variabel System.out merupakan output stream standar yang
menuliskan informasi byte ke layar monitor.
OutputStream memiliki beberapa method sebagai berikut :
a.
b.
public abstract void write( byte[] cbuf, int off, int len) throws
IOException
Method ini menuliskan sebagian isi array byte ke tujuan data dengan parameter off adalah offset /
nomor indeks dimulai pembacaan array, sedangkan len merepresentasikan panjang byte yang akan
dibaca.
c.
d.
Contoh kode program berikut menunjukkan cara informasi dimasukkan melalui keyboard kemudian
dicetak ke dalam file.
162
Contoh 16.2
import java.io.*;
public class InputOutput2{
FileOutputStream fos = null;
BufferedInputStream bis = null;
File file = null;
int hasil;
public static void main(String[] args){
InputOutput2 io2 = new InputOutput2();
}
public InputOutput2(){
try{
file = new File("io2.txt");
fos = new FileOutputStream(file);
bis = new BufferedInputStream(System.in);
while((hasil=bis.read())!=-1){
fos.write(hasil);
System.out.println(hasil);
}
fos.close();
bis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
Pada contoh program di atas dilakukan penyalinan data yang dikirim oleh keyboard ke file bernama
io2.txt. Data dari keyboard ditangani oleh obyek bis (BufferedInputStream). Program di atas
menggunakan method read(). Jika method read() menghasilkan nilai -1, maka pembacaan sudah
mencapai akhir stream. Selanjutnya program tersebut menampilkan data yang dikirim dari keyboard
dan menuliskannya ke file io2.txt.
163
Reader adalah node stream yang berfungsi melakukan pembacaan data karakter dari sumber data.
Beberapa method pada Reader antara lain :
a.
b.
c.
d.
e.
f.
public
void mark(int readlimit) throws IOException
Method ini menandai posisi terakhir pada input stream. Argumen readlimit menunjukkan posisi
mark di mana byte yang dibaca sebelum posisi mark tersebut dianggap invalidate.
Pada Java API, Reader merupakan sebuah kelas abstrak. Untuk dapat menggunakan obyek Reader
dalam program, programmer dapat melakukan instanstiasi obyek dari turunan kelas Reader.
Beberapa kelas turunan dari Reader antara lain :
a.
BufferedReader
Kelas ini merupakan kelas turunan Reader yang membaca teks dari character-input-stream
kemudian melakukan buffering.
b.
InputStreamReader
Kelas ini merupakan kelas turunan Reader yang merupakan jembatan dari byte stream ke
character stream. Kelas ini mempunyai turunan, yaitu FileReader yang membaca karakter dari
sebuah file.
InputStreamReader biasanya digunakan untuk menerima data byte dari sumber data dan langsung
mengkonversikannya ke format karakter. Method yang digunakan untuk membaca data sama seperti
InputStream, yaitu read(). Meskipun fungsinya sebagai konverter dari data byte ke karakter,
method-method pada InputStreamReader tidak menampilkan nilai karakter dari byte yang
dikonversikan.
Tidak adanya method yang menampilkan atau mengembalikan nilai karakter mengakibatkan
implementasi reader ini dalam program selalu dipasangkan dengan sebuah obyek dari kelas
BufferedReader. Kelas BufferedReader memiliki method yang dapat mengembalikan String,
yaitu public String readLine () throws IOException yang membaca satu baris teks.
Penggunaan InputStreamReader ditunjukkan pada contoh kode program berikut.
164
Contoh 16.3
import java.io.*;
public class ReaderExample{
BufferedReader bufReader = null;
InputStreamReader isr = null;
public static void main(String[] args){
ReaderExample re = new ReaderExample();
}
public ReaderExample(){
try{
isr = new InputStreamReader(System.in);
bufReader = new BufferedReader(isr);
String hasil;
while((hasil=bufReader.readLine())!=null){
System.out.println("Baris yang dibaca = : + hasil);
}
bufReader.close();
isr.close();
}catch(IOException e){}
}
}
Pada Contoh 16.3 di atas kelas ReaderExample memiliki atribut yaitu obyek BufferedReader
bufReader, dan obyek InputStreamReader isr. Pada konstruktor ReaderExample(),
terdapat baris-baris kode yang menginstanstiasi atribut-atribut kelas ReaderExample. Atribut isr
membaca input dari keyboard (System.in). Hasil pembacaan oleh isr akan dimasukkan ke dalam
buffer yang berada dalam atribut bufReader. Setelah instanstiasi atribut dilakukan looping while,
yang mempunyai eksperis boolean, untuk mengambil data dari bufReader. Looping while akan
terus dijalankan sampai pembacaan mencapai akhir dari stream. Jika program keluar dari loop while,
maka atribut-atribut bufReader dan isr ditutup.
Ketika program dijalankan, program akan menunggu masukan dari keyboard. Diasumsikan bahwa
pengguna memasukkan karakter-karakter Aku belajar Java, lalu menekan tombol ENTER. Output yang
ditampilkan pada layar monitor adalah sebagai berikut :
Baris yang dibaca = :Aku belajar Java
Contoh program di atas belum memperlihatkan kemampuan kelas BufferedReader yang dapat
membaca data yang terdiri atas beberapa baris. Pada contoh program berikut ditunjukkan cara untuk
membaca data dari sebuah file dan kemudian menampilkan isi file tersebut ke layar monitor.
Contoh 16.4
import java.io.*;
public class ReaderFromFileExample{
BufferedReader bufReader = null;
FileReader fr = null;
public static void main(String[] args){
ReaderFromFileExample re = new ReaderFromFileExample();
}
165
public ReaderFromFileExample(){
try{
fr = new FileReader(new File("source.txt"));
bufReader = new BufferedReader(fr);
String hasil;
while((hasil=bufReader.readLine())!=null){
System.out.println("Baris yang dibaca = :" + hasil);
}
bufReader.close();
fr.close();
}catch(IOException e){x}
}
}
Pada contoh di atas pembacaan file dilakukan menggunakan FileReader (obyek fr) dan
BufferedReader (obyek bufReader). Obyek fr membaca data dari file source.txt.
Karakter-karakter yang telah dibaca oleh fr akan di-buffer oleh bufReader. Skema ini dapat juga
dibuat dengan memasukkan file source.txt sebagai argumen dari konstruktor FileReader dan
memasukkan obyek fr sebagai argumen dari konstruktor BufferedReader.
Pembacaan file source.txt dilakukan dengan menggunakan method readLine() dari obyek
bufReader. Selanjutnya, dilakukan looping yang akan berakhir ketika pembacaan sudah mencapai
akhir dari stream. Hasil pembacaan akan ditampilkan di layar monior.
Setelah program pada contoh di atas dikompilasi dan dieksekusi, pada layar monitor akan muncul hasil
sebagai berikut :
Baris yang dibaca = :Saya sedang belajar pemrograman
berorientasi obyek
Baris yang dibaca = :Pemrogramannya menggunakan Java
Baris yang dibaca = :Ternyata pemrograman dengan Java
sungguh mengasyikkan
Writer adalah node stream yang berfungsi melakukan penulisan data karakter ke tujuan data.
Beberapa method Writer adalah sebagai berikut :
a.
b.
public abstract void write( char[] cbuf, int off, int len) throws
IOException
Method ini menuliskan sebagian isi array karakter ke tujuan data, dengan parameter off adalah
offset/nomor indeks di mana pembacaan karakter dimulai. Sedangkan len merepresentasikan
panjang karakter yang akan dibaca.
c.
d.
166
Contoh 16.5
import java.io.*;
public class WriteToFileExample{
FileReader fr = null;
BufferedReader bufReader = null;
BufferedWriter bufWriter = null;
FileWriter fw = null;
public static void main(String[] args){
WriteToFileExample wtfe = new WriteToFileExample();
}
public WriteToFileExample(){
try{
fr = new FileReader("source.txt");
fw = new FileWriter("destination.txt");
bufReader = new BufferedReader(fr);
bufWriter = new BufferedWriter(fw);
String hasil = bufReader.readLine();
while(hasil!=null){
System.out.println(hasil);
bufWriter.write(hasil,0,hasil.length());
bufWriter.flush();
bufWriter.newLine();
hasil = bufReader.readLine();
}
bufReader.close();
bufWriter.close();
}catch(IOException e){}
}
}
Pada contoh di atas terdapat obyek yang membaca data dari file, yaitu obyek fr yang merupakan
instance dari kelas FileReader. Selain itu, juga terdapat obyek yang menulis data ke file, yaitu obyek
fw yang merupakan instance dari kelas FileWriter. Atribut lainnya adalah obyek
BufferedReader bufReader dan BufferedWriter bufWriter yang berfungsi untuk
menampung data yang dibaca oleh fr dan menuliskan data tersebut ke fw.
Pada konstruktor WriteToFileExample() fr diinstanstiasi dengan menggunakan konstruktor
FileReader(String src) di mana fr didefinisikan sebagai FileReader yang membaca data
dari file source.txt.
Obyek fw diinstanstiasi dengan menggunakan konstruktor
FileWriter(String dest), di mana fw didefinisikan sebagai FileWriter yang menulis data
ke file destination.txt. Selanjutnya, bufReader diinstanstiasi dengan menggunakan konstruktor
BufferedReader(Reader in) di mana bufReader berfungsi untuk menampung data yang
dibaca oleh fr. Atribut bufWriter diinstanstiasi dengan menggunakan konstruktor
BufferedWriter(Writer out) di mana bufWriter berfungsi untuk menulis data ke fw.
Proses pembacaan file source.txt selanjutnya dilakukan dalam looping. Selama pembacaan
bufReader belum mencapai akhir dari stream, maka proses pembacaan file diteruskan, dan hasilnya
disalin ke variabel hasil. Pembacaan file tersebut dilakukan dengan memanggil method readLine()
milik obyek bufReader.
Nilai variabel hasil akan ditulis ke file destination.txt dengan memanggil method write() dari obyek
bufWriter. Method flush() dari obyek bufWriter dipanggil untuk memastikan bahwa
penulisan data ke file tujuan sudah dilakukan. Setelah pembacaan dan penulisan data selesai dilakukan,
dilakukan penutupan bufReader, dan bufWriter.
Untuk menjalankan contoh di atas, terlebih dahulu harus dipersiapkan file source.txt dan diisi dengan
kalimat bebas, misalnya :
Saya sedang belajar Java
Ternyata pemrograman Java itu mudah
Percaya atau tidak ?
167
Keluaran dari program pada contoh di atas adalah sebuah file destination.txt yang berisi data :
Saya sedang belajar Java
Ternyata pemrograman Java itu mudah
Percaya atau tidak ?
System.out merupakan sebuah obyek PrintStream yang mengacu ke sebuah layar terminal;
System.in merupakan sebuah obyek InputStream yang mengacu ke keyboard pengguna;
System.err merupakan sebuah obyek PrintStream yang mengacu ke sebuah layar terminal.
void
void
void
void
void
void
void
void
println(boolean)
println(char)
println(double)
println(float)
println(int)
println(long)
println(char[])
println(Object)
Selain itu, dapat digunakan satu overloaded method, yaitu method print yang tidak menambahkan
karakter baris baru di ujungnya.
Kode program berikut ini menunjukkan cara yang dapat digunakan untuk membaca String dari
console input standar :
Contoh 16.6
import java.io.*;
public class KeyboardInput {
public static void main(String[] args) {
String s;
InputStreamReader ir = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(ir);
System.out.println("unix: type ctrl-d or ctrl-c to exit."+
"\nwindows: type ctrl-z to exit");
try {
s = in.readLine();
while(s != null) {
System.out.println("read: " + s);
s = in.readLine();
}
in.close();
} catch(IOException e) {
e.printStackTrace();
}
}
168
Pada baris 5, dideklarasikan variabel dengan tipe String yang digunakan untuk menampung setiap
baris yang dibaca dari input standar. Baris 6-7 membungkus obyek System.in dengan dua obyek
pendukung. Obyek InputStreamReader (ir) membaca karakter dari bentuk raw bytes dan
mengubahnya ke dalam bentuk karakter Unicode. Obyek BufferedReader (in) menyediakan
method getLine() yang memungkinkan program untuk membaca dari input standar baris per
baris.
Kode Contoh 16.6 di atas membaca baris teks pertama dari input standar. Pengulangan while
mencetak baris yang dibaca dan kemudian membaca baris berikutnya. Kode di atas dapat ditulis
kembali dengan cara yang berbeda sebagai berikut:
Karena method readLine dapat melemparkan exception I/O, maka pernyataan di atas harus
diletakkan di dalam blok try-catch.
Selanjutnya input stream ditutup dengan pernyataan y in.close()untuk melepaskan sumber daya
sistem yang terkait dengan pembuat obyek stream ini.
Bentuk konstruktor yang digunakan tergantung obyek File lainnya yang akan diakses. Sebagai contoh,
jika hanya menggunakan satu file, maka gunakan bentuk konstruktor yang pertama. Tetapi, jika
menggunakan beberapa file sekaligus dari sebuah direktori, maka akan lebih mudah jika menggunakan
bentuk yang kedua.
Berikut ini method-method untuk pengujian dan pengecekkan kelas File :
1.
boolean exists()
Method ini mengembalikan nilai boolean true jika file atau direktori yang dirujuk oleh obyek File
tersedia.
2.
boolean isDirectory()
Method ini mengembalikan nilai boolean true jika obyek File merujuk ke sebuah direktori dan
false jika sebaliknya.
3.
boolean isFile()
Method ini mengembalikan nilai boolean true jika obyek File merujuk ke sebuah file dan false
jika sebaliknya;
169
4.
boolean canRead()
Method ini mengembalikan nilai boolean true jika proses pembacaan file yang dirujuk oleh obyek
File diizinkan dan false jika sebaliknya. Method ini dapat melemparkan exception
SecurityException jika akses untuk membaca file tidak diizinkan.
5.
boolean canWrite()
Method ini mengembalikan nilai boolean true jika proses penulisan file yang dirujuk oleh obyek
File diizinkan dan false jika sebaliknya. Method ini dapat melemparkan exception
SecurityException jika akses untuk menulis ke file tidak diizinkan.
String getName()
Mengembalikan obyek String yang berisikan nama file tanpa path nya. Untuk sebuah obyek
File yang merepresentasikan sebuah direktori, yang dikembalikan adalah nama direktorinya
saja.
2.
String getPath()
Mengembalikan obyek String yang berisikan path ke file tersebut termasuk nama file atau
direktorinya.
3.
String getAbsolutePath()
Mengembalikan obyek String yang berisikan absolute path dari file atau direktori yang dirujuk
oleh obyek File.
4.
String getParent()
Mengembalikan obyek String yang berisikan nama direktori induk (parent directory) dari file
atau direktori yang di-refer oleh obyek File.
5.
String length()
Mengembalikan nilai (dalam bentuk long) berupa panjang byte dari obyek File yang
bersangkutan.
2.
boolean mkdir()
Method ini membuat sebuah direktori yang direpresentasikan oleh obyek File.
3.
boolean delete()
menghapus file atau direktori yang dirujuk oleh obyek File. Jika proses penghapusan berhasil,
method ini akan mengembalikan nila true.
Kode program berikut ini membaca file teks dan mencetak setiap baris ke output standar:
Contoh 16.7
import java.io.*;
public class ReadFile {
public static void main(String[] args) {
File file = new File(args[0]);
try {
//buat sebuah buffered reader untuk baca tiap baris file
BufferedReader in = new BufferedReader(new FileReader(file));
String s = in.readLine();
170
while(s != null) {
System.out.println("read: " + s);
s = in.readLine();
}
in.close();
} catch(FileNotFoundException e1) {
//if this file doesn't exist
System.err.println("file not found: " + file);
} catch(IOException e2) {
//catch any other IO exception
e2.printStackTrace();
}
}
}
Pada baris ke-4, dibuat sebuah obyek File dengan menggunakan input dari argumen command line
program. Pada baris ke-9, dibuat sebuah buffered reader yang membungkus sebuah FileReader.
Kode
pada
baris
ini
(konstruktor
FileReader)
akan
melemparkan
exception
FileNotFoundException jika file tidak berhasil ditemukan. Blok pada pengulangan while
membaca setiap baris teks dalam BufferedReader dan mencetaknya ke output standar.
Selanjutnya, BufferedReader ditutup, yang juga akan menutup FileReader. Kode penanganan
exception akan menangkap exception FileNotFoundException yang dilempar oleh konstruktor
FileReader. Beberapa exception I/O lainnya ditulis untuk menangani exception yang mungkin saja
dilempar oleh method readLine dan close.
Contoh program berikut akan membaca input dari keyboard dan memasukkannya ke dalam file.
Contoh 16.8
import java.io.*;
public class WriteFile{
public static void main(String[] args) {
File file = new File(args[0]);
try {
BufferedReader in=
new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new FileWriter(file));
String s;
System.out.print("Masukkan teks di sini");
System.out.println("type ctrl-d (or ctrl-z) to stop.");
while((s = in.readLine()) != null) {
out.println(s);
}
in.close();
out.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
Seperti halnya pada contoh sebelumnya, pada Contoh 16.8 dibuat sebuah obyek File berdasarkan
argumen command line. Selanjutnya, dibuat sebuah BufferedReader untuk input standar.
Program juga membuat sebuah PrintWriter yang membungkus sebuah FileWriter untuk
menuliskan teks ke suatu file. Selanjutnya, Penggalan kode di atas memberikan pesan kepada pengguna
untuk memasukkan teks dan mengetikkan Ctrl-D untuk mengakhiri program. Selanjutnya, program
menuliskan teks input ke dalam file. Akhirnya, input dan output stream ditutup.
171
Berikut ini merupakan daftar konstanta yang ada di dalam kelas Math :
a.
b.
Method di dalam kelas Math merupakan method statik sehingga untuk mengaksesnya digunakan nama
kelasnya. Bentuk umum dari pemanggilan method pada kelas Math adalah sebagai berikut :
result = Math.aStaticMathMethod();
Berikut ini beberapa method yang biasa digunakan :
abs()
Method ini mengembalikan nilai absolut dari argumennya. Sebagai contoh :
x = Math.abs(99);
//output is 99
x = Math.abs(-99); //output is 99
Method ini memiliki versi overloaded-nya dengan argumen berupa int, long, float, dan double.
Bentuk dari method abs adalah sebagai berikut :
1.
2.
3.
4.
public
public
public
public
static
static
static
static
int abs(int a)
long abs(long a)
float abs(float a)
double abs(double a)
ceil()
Method ini mengembalikan nilai integer yang terkecil (dalam bentuk double) yang lebih besar atau
sama dengan nilai argumennya. Sebagai contoh, semua pemanggilan method di bawah ini
menghasilkan nilai double 9.0 :
Math.ceil(9.0);
Math.ceil(8.8);
Math.ceil(8.02);
//result is 9.0
//rises to 9.0
//still rises to 9.0
Perlakuan terhadap nilai negatif memiliki bentuk yang sama. Yang patut diingat adalah nilai -9 lebih
besar dari -10. Sebagai contoh, semua pemanggilan method di bawah ini menghasilkan nilai double 9.0:
Math.ceil(-9.0);
Math.ceil(-9.4);
Math.ceil(-9.8);
//result is -9.0
//rises to -9.0
//still rises to -9.0
172
floor()
Method ini mengembalikan nilai integer yang terbesar (dalam bentuk double) yang lebih kecil atau
sama dengan nilai argumennya. Method ini merupakan lawan dari method ceil. Sebagai contoh,
semua pemanggilan method di bawah ini menghasilkan nilai double 9.0 :
Math.floor(9.0);
Math.floor (9.4);
Math.floor (9.8);
//result is 9.0
//drops to 9.0
//still drops to 9.0
Perlakuan terhadap nilai negatif memiliki bentuk yang sama. Yang patut diingat adalah nilai -9 lebih
kecil dari -8. Sebagai contoh, semua pemanggilan method di bawah ini menghasilkan nilai double -9.0 :
Math.floor(-9.0);
Math.floor(-8.8);
Math.floor(-8.1);
//result is -9.0
//drops to -9.0
//still drops to -9.0
max()
Method ini menggunakan dua buah argumen dan mengembalikan nilai yang paling besar di antara
kedua nilai tesebut. Sebagai contoh :
x = Math.max(1024, -5000);
//output is 1024
Method ini memiliki versi overloaded-nya dengan argumen berupa int, long, float, dan double.
Jika kedua argumen memiliki nilai yang sama, maka method max() akan mengembalikan nilai yang
sama dengan argumen tersebut. Bentuk dari method max adalah sebagai berikut :
a.
b.
c.
d.
public
public
public
public
static
static
static
static
min()
Method ini merupakan lawan dari method max. Method ini menggunakan dua buah argumen dan
mengembalikan nilai yang paling kecil di antara kedua nilai tesebut. Sebagai contoh :
x = Math.min(0.5, 0.0);
//output is 0.0
Method ini memiliki versi overloaded-nya dengan argumen berupa int, long, float, dan double.
Jika kedua argumen memiliki nilai yang sama, maka method min() akan mengembalikan nilai yang
sama dengan argumen tersebut. Bentuk dari method min() adalah sebagai berikut :
1.
2.
3.
4.
public
public
public
public
static
static
static
static
173
random()
Method ini mengembalikan nilai random (berupa double) yang sama atau lebih besar dari 0.0 dan
lebih kecil dari 1.0. Method ini tidak menggunakan argumen apapun. Sebagai contoh :
x = Math.random();
Signature dari method random() adalah sebagai berikut :
public static double random()
round()
Method ini mengembalikan nilai integer yang paling dekat dengan nilai argumennya. Algoritma dari
method ini adalah dengan menambahkan angka 0.5 ke dalam argumen dan membulatkan nilainya ke
nilai integer terdekat. Jika nilai angka di belakang koma lebih kecil dari 0.5, Math.round() memiliki
perilaku sama dengan method Math.floor(). Jika nilai angka setelah angka desimal dari
argumennya lebih besar dari 0.5, Math.round() memiliki perilaku sama dengan method
Math.ceil(). Sebagai contoh :
x = Math.round(5.3);
y = Math.round(5.8);
//output is 5
//output is 6
sin()
Method ini mengembalikan nilai sinus dari sebuah sudut. Argumen yang digunakan adalah nilai
double yang merepresentasikan nilai sudut dalam radian. Nilai sudut dalam bentuk derajat (degree)
dapat diubah nilainya ke dalam bentuk radian dengan menggunakan Math.toRadians(). Sebagai
contoh :
Math.sin(Math.toRadians(90.0));
//returns 1.0
cos()
Method ini mengembalikan nilai cosinus dari sebuah sudut. Argumen yang digunakan adalah double
yang merepresentasikan nilai sudut dalam radian. Sebagai contoh :
Math.cos(Math.toRadians(0.0)); //returns 1.0
Signature dari method cos adalah sebagai berikut :
public static double cos(double a)
tan()
Method ini mengembalikan nilai tangen dari sebuah sudut. Argumen yang digunakan adalah double
yang merepresentasikan nilai sudut dalam radian. Sebagai contoh :
Math.tan(Math.toRadians(45.0));
174
//returns 1.0
sqrt()
Method ini mengembalikan akar dari sebuah nilai yang berbentuk double. Sebagai contoh :
Math.sqrt(9.0);
//returns 3.0
//returns 360.0
toRadians()
Method ini menggunakan argumen yang merepresentasikan nilai sudut dalam bentuk derajat dan
mengembalikannya dalam bentuk radian. Sebagai contoh:
Math.toRadians(360.0); //returns 6.283185 which is 2 * Math.PI
175
String x = taxi;
System.out.println(x.concat( cab));
Operator + dan += memiliki fungsi yang serupa dengan method concat() dalam kelas String.
Sebagai contoh :
String x = library;
System.out.println(x + card);
atau
String x = Atlantic;
x += ocean;
System.out.println(x);
String x = Exit;
System.out.println(x.equalsIgnoreCase(EXIT));// true
System.out.println(x.equalsIgnoreCase(tixe));// false
String x = 01234567;
System.out.println(x.length());
//return 8
176
String x = oxoxox;
System.out.println(x.replace(x, X));// oXoXoX
String
substring(int
Method ini digunakan untuk mengembalikan bagian (substring) dari String. Argumen pertama
menunjukkan awal dari substring (dengan indeks mulai dari nol). Jika pemanggilan method ini hanya
menggunakan satu argumen, maka String yang dikembalikan adalah mulai dari indeks yang
ditunjukkan oleh argumen begin hingga akhir dari String. Sedangkan jika pemanggilan method ini
memiliki dua argumen, maka substring yang dikembalikan adalah mulai dari indeks yang ditunjukkan
oleh argumen begin hingga indeks yang ditunjukkan oleh argumen end. Hal yang patut diingat
adalah argumen kedua tidak dimulai dari nol, melainkan dimulai dari satu. Sebagai contoh :
String x = 0123456789;
System.out.println(x.substring(5));// 56789
System.out.println(x.substring(5, 8));// 567
Pada contoh pertama, dimulai dari indeks ke-5 (zero-based) hingga akhir dari String. Tetapi, pada
contoh kedua dimulai dari indeks ke-5 (zero-based), yaitu 5 hingga indeks ke-7 (not zero-based).
String x = hi ;
System.out.println(x + x); // hi x
System.out.println(x.trim() + x);// hix
16.17 Kelas StringBuffer
Obyek StringBuffer merupakan urutan karakter Unicode yang dapat diubah (mutable). Dianjurkan
untuk menggunakan StringBuffer ketika membuat banyak modifikasi terhadap suatu String.
Berikut ini merupakan bentuk-bentuk konstruktor yang ada di dalam kelas StringBuffer :
177
public StringBuffer()
Konstruktor ini membuat sebuah obyek StringBuffer yang kosong. Sebagai contoh :
StringBuffer sb1 = new StringBuffer();
public StringBuffer(int capacity)
Konstruktor ini membuat sebuah obyek StringBuffer kosong dengan kapasitas sebesar int.
Sebagai contoh :
StringBuffer sb2 = new StringBuffer(50);
Kode di atas akan membuat sebuah obyek StringBuffer yang memiliki kapasitas 50 karakter.
178
menyediakan mekanisme untuk membungkus data primitif ke dalam obyek sehingga data primitif
ini dapat menggunakan operasi-operasi yang khusus diperuntukkan untuk obyek, seperti
penambahan ke dalam koleksi atau pengembalian dari sebuah method yang mengembalikan
sebuah obyek;
b.
menyediakan satu set fungsi utility untuk data primitif. Sebagian besar dari fungsi-fungsi ini
berhubungan dengan konversi data primitif dari satu bentuk ke bentuk yang lainnya, sebagai
contoh, mengubah data primitif ke dalam bentuk String dan sebaliknya, mengubah data primitif
ke dalam bentuk basis yang berbeda-beda (binary, octal, dan decimal).
Setiap data primitif dalam Java memiliki kelas wrapper yang bersesuaian. Sebagai contoh, kelas wrapper
untuk int adalah Integer, untuk float adalah Float, dan sebagainya. Yang patut diingat adalah
nama dari kelas wrapper suatu data primitif adalah sama dengan tipe data primitif yang bersesuaian
dengan huruf pertamanya dalam bentuk huruf besar, kecuali untuk tipe data char dengan kelas
wrapper Character, dan int dengan kelas wrapper Integer. Tabel di bawah ini menunjukkan tipe
data primitif dan kelas wrapper yang bersesuaian :
Tabel 16.2
Data Primitif dan Kelas Wrapper yang Sejenis Beserta Konstruktornya
TIPE DATA
PRIMITIF
boolean
byte
char
short
int
long
float
double
KELAS
WRAPPER
Boolean
Byte
Character
Short
Integer
Long
Float
Double
ARGUMEN KONSTRUKTOR
boolean atau String
byte atau String
char
short atau String
int atau String
long atau String
float atau String
double atau String
Obyek wrapper bersifat immutable, yang berarti bahwa sekali diberikan nilai pada sebuah obyek
wrapper, nilainya tidak dapat diubah.
Semua kelas wrapper, (kecuali Character), menyediakan dua buah konstruktor: satu konstruktor
menggunakan nilai primitif yang bersesuaian, dan konstruktor yang lain menggunakan String yang
merupakan representasi dari data primitif yang akan dibungkus di dalam kelas wrapper.
Integer i1 = new Integer(42);
Integer i2 = new Integer(42);
atau
Float f1 = new Float(3.14);
Float f2 = new Float(3.14);
Untuk kelas wrapper Character, ia hanya menyediakan satu buah konstruktor, yang mengambil nilai
char sebagai argumen. Sebagai contoh :
Character c1 = new Character(c);
179
Method statik valueOf() yang disediakan di sebagian besar kelas wrapper (kecuali kelas wrapper
Character) memberikan cara lain untuk membuat obyek wrapper. Method ini menggunakan
String yang merepresentasikan data primitif yang bersesuaian sebagai argumen pertama, dan
argumen kedua (jika ada) sebagai basis dari nilai pada argumen pertama. Sebagai contoh:
Integer i2 = Integer.valueOf(100);
Integer i3 = Integer.valueOf(101011, 2);
atau
Float f2 = Float.valueOf(3.14f);
Berikut ini method yang biasa digunakan dalam kelas wrapper untuk mengkonversi suatu nilai.
xxxValue()
Ketika ingin mengubah obyek wrapper ke dalam data primitif, dapat digunakan salah satu dari method
xxxValue() ini. Semua method ini tidak menggunakan argumen.
Tabel 16.3
Tabel Method dalam Kelas Wrapper
Method
s = static
Boolean
n = NFE exception
byteValue
doubleValue
floatValue
intValue
longValue
shortValue
parseXxx s,n
parseXxx s,n
(with radix)
Byte
Double
Float
Integer
Long
Float
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x
valueOf s,n
valueOf s,n
(with radix)
x
x
toString
toString s
(primitive)
toString s
(primitive, radix)
x
x
Character
Sebagai contoh :
Integer i2 = new Integer(42);
byte b = i2.byteValue();
short s = i2.shortValue();
double d = i2.doubleValue();
atau
Float f2 = new Float(3.14f);
short s = f2.shortValue();
System.out.println(s);
180
toString()
Setiap kelas wrapper memiliki method toString() yang tidak memiliki argumen dan tidak statik.
Method ini mengembalikan nilai berupa obyek String yang merepresentasikan nilai primitif yang
dibungkus oleh kelas wrapper-nya. Sebagai contoh :
Double d = new Double("3.14");
System.out.println("d = " + d.toString() );
Selain itu, semua kelas wrapper yang bertipe numerik mempunyai versi overloaded dari method
toString() ini. Masing-masing method tersebut mengambil argumen berupa tipe numerik yang
bersesuaian (Double.toString() mengambill nilai double, Long.toString() mengambil
nilai long, dan sebagainya). Sebagai contoh :
System.out.println("d = " + Double.toString(3.14);
Kelas wrapper Integer dan Long memiliki bentuk ketiga dari method toString(). Method ini
bertipe statik, argumen pertamanya adalah nilai primitif yang bersesuaian, dan argumen keduanya
merupakan basis. Method ini mengembalikan nilai berupa String yang merepresentasikan nilai
primitif dalam bentuk basis yang sesuai dengan argumen kedua nya. Sebagai contoh :
System.out.println("hex = " + Long.toString(254,16); //"hex = fe"
Collection merupakan sekumpulan obyek yang disebut sebagai elemen. Implementasi dari
Collection ini akan menentukan apakah ada aturan mengenai ordering tertentu dan apakah
duplikasi elemen diperbolehkan di dalamnya.
Set merupakan sebuah koleksi yang tidak memiliki aturan unordered di mana di dalamnya tidak
boleh ada duplikasi elemen.
List merupakan sebuah koleksi yang memiliki aturan ordered di mana di dalamnya duplikasi
elemen diperbolehkan.
Semua jenis koleksi memiliki referensi ke obyek-obyek dengan tipe Object. Hal ini memungkinkan
semua jenis obyek untuk disimpan di dalam koleksi. Implikasi dari elemen dalam koleksi yang bertipe
181
Object adalah harus digunakan proses casting yang benar ketika mengambil sebuah elemen dari
dalam koleksi.
<<interface>>
Collection
+
+
+
+
+
+
<<interface>>
List
<<interface>>
Set
HashSet
+
+
+
+
+
+
ArrayList
LinkedList
Kelas HashSet menyediakan implementasi dari interface Set sementara kelas ArrayList dan
LinkedList menyediakan implementasi bagi interface List.
16.19.1 Set
Dalam contoh kode berikut ini, dideklarasikan sebuah variabel (set) dengan tipe Set. Lalu diinisialisasi
variabel ini dengan sebuah obyek HashSet. Selanjutnya ditambahkan beberapa elemen ke dalamnya
dan mencetak isi dari variabel set ke output standar.
Contoh 16.9
import java.util.*;
public class SetExample {
public static void main(String[] args) {
Set set = new HashSet();
set.add("one");
set.add("second");
set.add(new Integer(4));
set.add("second");
//duplikasi, tidak ditambahkan
set.add(new Integer(4)); //duplikasi,tidak ditambahkan
System.out.println(set);
}
}
16.19.2 List
Dalam contoh kode berikut ini, dideklarasikan sebuah variabel (list) dengan tipe List. Selanjutnya,
variabel ini diinisialisasi dengan sebuah obyek ArrayList. Selanjutnya ditambahkan beberapa
elemen ke dalamnya dan mencetak isi dari variabel list ke output standar. Berbeda dengan contoh
sebelumnya, pada contoh ini berhasil dilakukan penambahan elemen yang terduplikasi.
182
Contoh 16.10
import java.util.*;
public class ListExample {
public static void main(String[] args) {
List list = new ArrayList();
list.add("one");
list.add("second");
list.add("3rd");
list.add(new Integer(4));
list.add(new Float(5.0F));
list.add("second");
//duplikasi ditambahkan
list.add(new Integer(4));
//duplikasi ditambahkan
System.out.println(list);
}
}
16.19.3 Iterator
Sebuah koleksi dapat diiterasi dengan menggunakan iterator. Interface Iterator memungkinkan
untuk melakukan iterasi secara forward. Pada kasus iterasi di dalam sebuah obyek Set, langkah
iterasinya tidak dapat ditentukan sementara langkah iterasi pada sebuah list adalah bergerak maju.
Sebuah obyek List juga mendukung penggunaan ListIterator yang memungkinkan proses iterasi
secara backward. Kode program di bawah ini menggambarkan penggunaan iterator:
List list = new ArrayList();
Iterator elements = new Iterator();
while(elements.hasNext()) {
System.out.println(elements.next());
}
<<interface>>
Iterator
+ hasNext() : boolean
+ next() : Object
+ remove()
<<interface>>
ListIterator
+
+
+
+
hasPrevious() : boolean
previous() : Object
add(element : Object)
set(element : Object)
Method remove digunakan untuk menghapus item di dalam sebuah iterasi. Jika salah satu koleksi tidak
mendukung proses penghapusan ini, maka exception UnsupportedOperationException akan
dilemparkan.
ListIterator bergerak satu arah, yaitu begerak maju dengan menggunakan method next() atau
mundur dengan menggunakan method previous(). Jika menggunakan method previous()
setelah menggunakan method next() akan diperoleh elemen sebelum memanggil method next().
Begitu juga sebaliknya.
Method set mengubah elemen yang ditunjuk oleh kursor iterator. Method add menambah elemen
baru ke dalam koleksi pada posisi sebelum kursor iterator. Dengan demikian, jika memanggil method
previous seteleh pemanggilan method add, akan diperoleh elemen yang baru dimasukkan ke dalam
koleksi tersebut. Jika proses penyetingan dan penambahan elemen tidak didukung oleh koleksi yang
bersangkutan, maka UnsupportedOperationException akan dilemparkan.
183
184
185
186
Pada Contoh 16.11 di atas konstruktor NetworkServer() memanggil method doAll(). Pada
method doAll() dilakukan instanstiasi obyek ServerSocket menggunakan konstruktor
ServerSocket(int port) dengan argumen port adalah 4444. hal ini berarti data yang diterima
dari jaringan harus memiliki nomor port 4444 pada header paketnya agar dapat diproses oleh server.
Obyek ServerSocket tersebut diberi nama serverSocket.
Setelah instanstiasi serverSocket selesai, langkah selanjutnya adalah menunggu request koneksi
dari client dengan cara memanggil method createConnection(). Method ini memanggil method
accept() milik obyek serverSocket. Method ini akan menunggu sampai ada client yang
mengirimkan request koneksi. Ketika ada request koneksi yang datang, method accept() akan
mengembalikan sebuah obyek Socket yang menangani informasi IP address dan nomor port client.
Obyek Socket tersebut diberi nama clientSocket.
Langkah berikutnya pada method createConnection() adalah instanstiasi obyek PrintWriter
bernama out yang menuliskan response ke Outputstream dari clientSocket. Setelah itu
dilakukan instanstiasi obyek BufferedReader bernama in yang membaca data yang dikirimkan oleh
client. Setelah method createConnection() selesai dieksekusi, method doAll() selanjutnya
memanggil method readStream().
Method readStream() mengandung skema pengulangan while dengan nilai ekspresi boolean
true sehingga pengulangan akan terus dilakukan, kecuali jika terjadi eksepsi IOException, misalnya
karena koneksi terputus. Di dalam pengulangan while, terdapat blok try...catch yang berisi
pengulangan while dengan ekspresi boolean sebagai berikut.
(inputLine=in.readLine())!=null
hal ini berarti pengulangan akan dijalankan apabila pembacaan data oleh obyek in tidak menghasilkan
nilai null. Pembacaan data dilakukan dengan memanggil method readLine() milik obyek in. Data
yang dibaca disimpan ke variabel inputLine untuk kemudian ditampilkan di layar monitor server.
Pada method readStream() dipanggil method sendResponse() dengan inputLine sebagai
argumennya. Method sendResponse() akan membentuk response berupa String words yang
akan menuliskan Anda mengirim pesan ***** , di mana ***** adalah nilai literal dari inputLine.
Kemudian nilai words akan dituliskan ke OutputStream dari clientSocket.
Setelah data dikirimkan ke client, obyek clientSocket ditutup. Penutupan clientSocket akan
berakibat munculnya exception IOException pada method readStream(). Tetapi, program di
atas mengantisipasinya dengan memanggil kembali method createConnection() jika
IOException muncul sehingga server menunggu adanya request lanjutan dari client. Hal ini
disebabkan karena setelah server melakukan pengiriman response clientSocket otomatis ditutup,
sehingga perlu dilakukan pembentukan koneksi kembali agar server dapat menerima request
berikutnya dari client. Oleh karena itu, pada bagian catch method createConnection()
dipanggil. Dengan demikian, server dapat terus bekerja sampai waktu tak terbatas. Kode program untuk
client ditunjukkan berikut ini.
187
Contoh 16.12
import java.net.*;
import java.io.*;
public class
private
private
private
private
private
private
NetworkClient{
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedReader stdIn = null;
String userInput;
BufferedReader responseReader = null;
188
Pada contoh program di atas konstruktor NetworkClient() memanggil method doAll(). Method
doAll() memanggil method createConnection() untuk menjalin koneksi dengan server.
Method createConnection() menciptakan koneksi dengan menginstanstiasi obyek Socket
dengan nama socket menggunakan konstruktor Socket(String remoteHostAddress, int
remoteHostPort, String localHostAddress, int localHostPort). Konstruktor ini
menyebabkan client mengirim request koneksi ke server dengan IP address remoteHostAddress
dan nomor port remoteHostPort. Argumen localHostAddress adalah IP address dari client,
dan localHostPort adalah port yang digunakan oleh client untuk mengirimkan data. Ketika
melakukan spesifikasi nomor port, client menetapkan port localHostPort akan digunakan oleh
client untuk mengirimkan data dan juga menjadi port tujuan bagi server untuk mengirimkan response ke
client. Pada kasus di sini client akan mengirimkan request ke server dengan IP address 167.205.66.5 dan
port 4444. Sedangkan response dari server akan diterima oleh client pada port 3333.
Method createConnection() menginstanstiasi obyek PrintWriter out yang akan menuliskan
request ke OutputStream milik socket. Kemudian obyek BufferedReader in membaca
response yang diterima dari server. Untuk menampung informasi yang berasal dari keyboard, method
createControl() menginstanstiasi obyek BufferedReader stdIn yang membaca stream dari
keyboard.
Setelah koneksi berhasil dibuat, method doAll() masuk ke skema pengulangan while yang
mempunyai ekspresi boolean sebagai berikut :
(userInput=stdIn.readLine())!=null
hal ini berarti pengulangan akan terus dijalankan jika pembacaan dari keyboard belum mencapai akhir
stream. Dalam pengulangan while setiap request yang masuk dari keyboard akan dituliskan ke
OutputStream milik socket. Setelah mengirimkan request, doAll() memanggil method
receive() untuk menerima response dari server.
Method receive() membaca isi dari InputStream dari socket dan menyalinnya ke variabel
nextLine menggunakan method readLine(). Method readLine()memblok proses sampai
response dari server masuk ke client. Setelah response diterima, client akan menampilkan response
tersebut ke monitor. Setelah itu socket ditutup. Setelah method receive() selesai dieksekusi,
langkah selanjutnya adalah membentuk koneksi kembali dengan server untuk mengirimkan request
berikutnya dengan memanggil method createConnection().
Output dari kedua aplikasi ini adalah sebagai berikut :
Tabel 16.4
Tabel Output Aplikasi Client Server Contoh 16.11 dan Contoh 16.12
Server
Client
Ini
Membangun Koneksi :
Local Address : /167.205.66.4
Local Port Number : 3333
Remote Address 127.0.0.1
Remote Port Number 4444
============================
Masukkan Input / Request :
Ini Adalah
189
190
17
PEMROGRAMAN
GRAPHICAL USER INTERFACE
Graphical User Interface (GUI) merupakan interface grafis suatu aplikasi yang memfasilitasi interaksi
antara pengguna dengan program. Gambar berikut menunjukkan contoh tampilan GUI.
Java memiliki komponen untuk membangun GUI. Salah satu komponen tersebut adalah Swing.
Komponen Swing didefinisikan dalam paket javax.swing. Swing merupakan komponen GUI yang
diturunkan dari Abstract Windowing Toolkit dalam paket java.awt. Berikut gambar yang
menunjukkan hirarki komponen Swing.
JComponent adalah superclass dari semua komponen Swing. Sebagian besar fungsionalitas
komponen diturunkan dari superclass ini. Fungsionalitas tersebut meliputi :
a.
b.
c.
d.
17.16 Jlabel
Label merupakan komponen GUI yang berfungsi untuk menampilkan suatu teks. Teks tersebut biasanya
bersifat read-only. Umumnya programmer jarang sekali mengubah isi suatu label. Kelas untuk
menampilkan label di GUI berbasis Java bernama JLabel. Kelas ini diturunkan dari kelas
JComponent. Contoh penggunaan JLabel ditunjukkan pada gambar berikut.
191
Suatu teks label dapat diinisialisasi melalui konstruktor JLabel sebagaimana ditunjukkan pada
penggalan program berikut.
atau
label 2 = new JLabel(Institut Teknologi Telkom", ImageIcon,Text_Alignment_CONSTANT);
JLabel juga dapat menampilkan teks tool tip, yaitu teks yang muncul apabila mouse berada di atas
suatu teks label. Untuk menampilkan tool tip gunakan method berikut.
Selain inisialisasi teks melalui konstruktor JLabel, programmer juga dapat menggunakan method
setText untuk mengubah atau menyeting teks yang akan ditampilkan dengan menggunakan method
berikut.
myLabel.setText( "Text" );
Secara default, teks muncul di sebelah kanan image. Method setHorizontalTextPosition dan
setVerticalTextPosition dapat digunakan untuk menentukan lokasi teks yang akan
ditampilkan. Lokasi teks tersebut ditentukan oleh suatu konstanta integer yang didefiniskan dalam
interface SwingConstant pada paket javax.swing. Nilai konstanta tersebut meliputi
SwingConstants.LEFT, SwingConstants.RIGHT, SwingConstants.BOTTOM, dan
SwingConstants.CENTER. Untuk lebih memahami cara penggunaan JLabel, lihat contoh
program berikut.
192
Contoh 17.1
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LabelTest extends JFrame {
private JLabel label1, label2, label3;
public LabelTest(){
super("Testing Label");
generateGUI();
}
private void generateGUI(){
Container c = getContentPane();
c.setLayout(new FlowLayout());
label1 = new JLabel("Label dengan Text");
label1.setToolTipText("Ini adalah Label 1");
c.add(label1);
Icon bug = new ImageIcon("./image/javalogo.gif");
label2 = new JLabel("Label dengan text dan icon",SwingConstants.LEFT);
label2.setToolTipText("Ini adalah label 2");
c.add(label2);
label3 = new JLabel();
label3.setText("Label dengan icon dan text di bawahnya");
label3.setIcon(bug);
label3.setHorizontalTextPosition(SwingConstants.CENTER);
label3.setVerticalTextPosition(SwingConstants.BOTTOM);
label3.setToolTipText("Ini adalah label 3");
c.add(label3);
setSize(275,170);
show();
}
public static void main(String args[]){
LabelTest app = new LabelTest();
app.addWindowListener(
new WindowAdapter(){
public void
windowsClosing(WindowEvent e){
System.exit(0);
}
}
);
}
}
193
JTextField(10) yang mendefinisikan ukuran teks yang dapat ditulis sebesar 10 kolom;
2.
JTextField("Hi")
JTextField.;
3.
yang
mendefinisikan
teks
"Hi"
sebagai
tampilan
default
dari
setEditable(boolean). Jika nilai boolean false, maka pengguna tidak dapat mengedit teks
pada JTextField, namun masih dapat mengaktifkan suatu event;
2.
getPassword(). Method ini merupakan method milik kelas JPasswordField. Method ini
mengembalikan teks password berupa Array suatu karakter.
JTextField
dan
JPasswordField
memiliki
kelas
ActionEvent.
Method
getActionCommand mengembalikan teks yang tertulis pada JTextField. Method getSource
mengembalikan sebuah referensi Component. Untuk memahami lebih lanjut tentang penggunaan
JTextField dan JPasswordField, pelajari contoh program berikut ini.
Contoh 17.2
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TextFieldTest extends JFrame {
private JTextField text1, text2, text3;
private JPasswordField password;
public TextFieldTest(){
super("Penggunaan JTextfield dan JPasswordField");
Container c = getContentPane();
c.setLayout(new FlowLayout());
text1 = new JTextField(10);
c.add(text1);
text2 = new JTextField("Ketik teks di sini");
c.add(text2);
text3 = new JTextField("Teks tak dpt diedit",20);
text3.setEditable(false);
c.add(text3);
password = new JPasswordField("Teks tersembunyi");
c.add(password);
TextFieldHandler handler = new TextFieldHandler();
text1.addActionListener(handler);
text2.addActionListener(handler);
text3.addActionListener(handler);
password.addActionListener(handler);
setSize(325,100);
show();
}
public static void main(String args[]){
TextFieldTest app = new TextFieldTest();
app.addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);
}
}
);
}
194
17.18 JButton
Button merupakan komponen mirip tombol. Button terdiri dari beberapa tipe, yaitu command button,
toggle button, check boxes, dan radio button.
Command button mengaktifkan ActionEvent ketika diklik. Command button diturunkan dari kelas
AbstractButton dan dibuat bersama dengan kelas JButton.
Di atas JButton dapat diletakkan suatu label teks, atau lebih dikenal sebagai Button label, dan suatu
gambar icon. Berikut contoh gambar JButton.
Teks label atau gambar icon yang akan ditulis di atas JButton dapat diinisialisasi melalui konstruktor
JButton berikut ini.
JButton myButton = new JButton( "Label" );
JButton myButton = new JButton( "Label",myIcon);
Method yang sering digunakan dalam JButton adalah sebagai berikut.
setRolloverIcon(myIcon);
getActionCommand();
Untuk lebih memahami penggunaan JButton pelajari contoh kode program berikut ini.
195
Contoh 17.3
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class ButtonTest extends JFrame {
private JButton plainButton, fancyButton;
public ButtonTest(){
super("Uji Coba Button:");
generateGUI();
}
private void generateGUI(){
Container c = getContentPane();
c.setLayout(new FlowLayout());
plainButton = new JButton("Tanpa Icon");
c.add(plainButton);
Icon bug1=new ImageIcon("./image/pic1.gif");
Icon bug2=new ImageIcon("./image/pic2.gif");
fancyButton=new JButton("Ada Icon", bug1);
fancyButton.setRolloverIcon(bug2);
c.add(fancyButton);
ButtonHandler handler = new ButtonHandler();
fancyButton.addActionListener(handler);
plainButton.addActionListener(handler);
setSize(300,300);
show();
}
public static void main(String args[]){
ButtonTest app = new ButtonTest();
app.addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);
}
}
);
}
private class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(null,"Anda menekan : " +
e.getActionCommand());
}
}
}
196
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class CheckBoxTest extends JFrame {
private JTextField t;
private JCheckBox bold, italic;
public CheckBoxTest(){
super ("Uji Coba JCheckBox");
Container c = getContentPane();
c.setLayout(new FlowLayout());
t = new JTextField("Perubahan Font", 20);
t.setFont(new Font("TimesRoman", Font.PLAIN,14));
c.add(t);
bold = new JCheckBox("Bold");
c.add(bold);
italic = new JCheckBox("Italic");
c.add(italic);
CheckBoxHandler handler = new CheckBoxHandler();
bold.addItemListener(handler);
italic.addItemListener(handler);
addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);}
}
);
setSize(275,100);
show();
}
public static void main(String args[]){
new CheckBoxTest();
}
197
Berbeda dengan JCheckBox, JRadioButtons memiliki dua status yaitu selected dan deselected.
Pada umumnya radio button ditampilkan dalam sebuah grup. Hanya satu radio button di dalam suatu
grup yang dapat dipilih pada satu waktu. Pemilihan satu button menyebabkan button lain berstatus off.
Gambar berikut menunjukkan contoh tampilan JRadioButton.
Jika nilai parameter selected adalah true, maka status awal JRadioButton adalah selected. Sama
halnya dengan JCheckBox, JRadioButton juga dapat mengaktifkan suatu ItemEvents. Berikut
ini penggalan program yang menggabungkan sebuah instance JRadioButton pada sebuah grup.
ButtonGroup myGroup = new ButtonGroup();
myGroup.add(myRadioButton);
Untuk lebih memahami penggunaan JRadioButton, pelajari contoh program berikut ini.
Contoh 17.5
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class RadioButtonTest extends JFrame {
private JTextField t;
private Font plainFont, boldFont;
private Font italicFont, boldItalicFont;
private JRadioButton plain, bold, italic, boldItalic;
private ButtonGroup radioGroup;
public RadioButtonTest(){
super("Uji Coba RadioButton");
Container c = getContentPane();
c.setLayout(new FlowLayout());
t = new JTextField("Perhatikan perubahan jenis huruf",30);
c.add(t);
plain = new JRadioButton("Plain", true);
c.add(plain);
bold = new JRadioButton("Bold", false);
c.add(bold);
italic = new JRadioButton("Italic",false);
c.add(italic);
boldItalic = new JRadioButton("Bold-Italic", false);
c.add(boldItalic);
RadioButtonHandler handler = new RadioButtonHandler();
plain.addItemListener(handler);
bold.addItemListener(handler);
italic.addItemListener(handler);
boldItalic.addItemListener(handler);
radioGroup = new ButtonGroup();
radioGroup.add(plain);
radioGroup.add(bold);
198
radioGroup.add(italic);
radioGroup.add(boldItalic);
plainFont=new Font("TimesRoman",Font.PLAIN,16);
boldFont=new Font("TimesRoman",Font.BOLD,16);
italicFont=new Font("TimesRoman",Font.ITALIC,16);
boldItalicFont = new Font("TimesRoman",Font.BOLD+Font.ITALIC,16);
t.setFont(plainFont);
setSize(300,500);
show();
}
public static void main(String args[]){
RadioButtonTest app = new RadioButtonTest();
app.addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);
}
}
);
}
private class RadioButtonHandler implements ItemListener{
public void itemStateChanged(ItemEvent e){
if (e.getSource()==plain) t.setFont(plainFont);
else if (e.getSource()==bold)
t.setFont(boldFont);
else if (e.getSource()==italic)
t.setFont(italicFont);
else if (e.getSource()==bold)
t.setFont(boldItalicFont);
t.repaint();
}
}
}
17.20 JComboBox
JComboBox merupakan komponen GUI untuk menampilkan daftar suatu item sebagaimana
ditunjukkan pada gambar berikut ini.
Kelas JComboBox juga dapat mengaktifkan ItemEvents. Konstruktornya adalah sebagai berikut :
JComboBox (arrayOfNames);
Setiap item di JComboBox diberi indeks numerik. Elemen pertama diberi indeks 0 dan elemen
tersebut dimunculkan sebagai item yang dipilih pada saat instance JComboBox tampil untuk pertama
kalinya. Method penting JComboBox adalah sebagai berikut :
a.
b.
Untuk lebih memahami penggunaan JComboBox, pelajari contoh kode program berikut ini.
199
Contoh 17.6
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ComboBoxTest extends JFrame {
private JComboBox images;
private JLabel label;
private String names[] = {"pic1.gif","pic2.gif","pic3.gif","pic4.gif"};
private Icon icons[] = {new ImageIcon("./image/" + names[0]),
new ImageIcon("./image/" + names[1]),
new ImageIcon("./image/" + names[2]),
new ImageIcon("./image/" + names[3])};
public ComboBoxTest(){
super ("Uji coba JComboBox");
Container c = getContentPane();
c.setLayout(new FlowLayout());
images = new JComboBox(names);
images.setMaximumRowCount(3);
images.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
label.setIcon(icons[images.getSelectedIndex()]);
}
});
c.add(images);
label = new JLabel(icons[0]);
c.add(label);
setSize(400,400);
show();
}
public static void main(String args[]){
ComboBoxTest app = new ComboBoxTest();
}
}
17.21 Jlist
Berbeda dengan JComboBox, JList menampilkan deretan item yang dapat dipilih satu atau lebih.
Berikut contoh gambar JList.
Kelas JList memiliki konstruktor JList(arrayOfNames). JList mengambil array obyek String.
Salah satu method JList penting adalah setVisibleRowCount(n) yang menampilkan jumlah n
item pada satu waktu, namun tidak secara otomatis membuat scrolling. Untuk membuat scrolling,
gunakan komponen JScrollPane berikut ini.
c.add(new JScrollPane(colorList));
200
Contoh 17.7
import
import
import
import
javax.swing.*;
java.awt.event.*;
javax.swing.event.*;
java.awt.*;
201
Untuk lebih jelasnya, perhatikan gambar berikut yang menunjukkan tipe daftar multiple selection.
Untuk lebih memahami penggunaan multiple selection di JList, pelajari contoh kode program
berikut.
Contoh 17.8
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MultipleSelectionTest extends JFrame{
private JList colorList, copyList;
private JButton copy;
private String colorNames[] = {"Black","Blue","Cyan","Dark Gray",
"Gray", "Green","Light Gray", "Magneta",
"Orange", "Pink", "Red", "White", "Yellow"};
public MultipleSelectionTest(){
super("Uji Coba Multiple Selection List");
Container c = getContentPane();
c.setLayout(new FlowLayout());
colorList = new JList(colorNames);
colorList.setVisibleRowCount(5);
colorList.setFixedCellHeight(15);
colorList.setSelectionMode(
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
c.add(new JScrollPane(colorList));
copy = new JButton("Copy >>");
copy.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
copyList.setListData(
colorList.getSelectedValues());
}
}
);
202
c.add(copy);
copyList = new JList();
copyList.setVisibleRowCount(5);
copyList.setFixedCellWidth(100);
copyList.setFixedCellHeight(15);
copyList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
c.add(new JScrollPane(copyList));
setSize(400,400);
show();
}
public static void main(String[] args) {
MultipleSelectionTest apps = new MultipleSelectionTest();
apps.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
);
}
}
17.22 JTextArea
JTextArea merupakan komponen yang biasanya digunakan untuk memanipulasi barisan teks. Seperti
halnya JTextField, JTextArea diturunkan dari JTextComponent dan memiliki method yang
sama. Berikut contoh gambar JTextArea.
Berikut ini Method JTextField yang juga dapat digunakan dalam JTextArea.
a.
b.
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;
JScrollPane.VERTICAL_SCROLLBAR_NEVER;
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS.
203
Contoh 17.9
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TextAreaTest extends JFrame {
private JTextArea t1, t2;
private JButton copy;
public TextAreaTest(){
super("Demostrasi JTextArea");
Box b = Box.createHorizontalBox();
String s = "Prodi Sistem Informasi\n" +
"Fakultas Rekayasa Industri\n" +
"Gedung C Lantai 3 \n" +
"Institut Teknologi Telkom\n" +
"www.ittelkom.ac.id";
t1 = new JTextArea(s,10,15);
b.add(new JScrollPane(t1));
copy = new JButton("Copy >>>");
copy.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
t2.setText(t1.getSelectedText());
}
}
);
b.add(copy);
t2 = new JTextArea(10,15);
t2.setEnabled(false);
b.add(new JScrollPane(t2));
Container c = getContentPane();
c.add(b);
setSize(400,400);
show();
}
public static void main(String[] args) {
TextAreaTest app = new TextAreaTest();
app.addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);
}
}
);
}
}
17.23.1 FlowLayout
FlowLayout menyusun komponen dari kanan ke kiri yang selanjutnya ke baris berikutnya. Ukuran
windows yang diperbesar tidak akan menyebabkan ukuran komponen yang berada di atas
FlowLayout berubah. Gambar berikut menunjukkan tampilan FlowLayout.
204
b.
Untuk lebih memahami penggunaan FlowLayout, pelajari contoh kode program berikut ini.
Contoh 17.10
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class FlowLayoutTest extends JFrame {
private JButton left, center, right;
private Container c;
private FlowLayout layout;
public FlowLayoutTest(){
super ("Demontrasi penggunaan FlowLayout");
layout = new FlowLayout();
c= getContentPane();
c.setLayout(layout);
left = new JButton("Left");
left.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e){
layout.setAlignment(FlowLayout.LEFT);
layout.layoutContainer(c);
}
}
);
c.add(left);
center = new JButton("Center");
center.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e){
layout.setAlignment(FlowLayout.CENTER);
layout.layoutContainer(c);
}
}
);
c.add(center);
right = new JButton("Right");
right.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e){
layout.setAlignment(FlowLayout.RIGHT);
layout.layoutContainer(c);
}
});
c.add(right);
setSize(500,500);
show();
}
public static void main(String[] args) {
FlowLayoutTest app = new FlowLayoutTest();
}
}
205
17.23.2 BorderLayout
BorderLayout merupakan default manager untuk ContentPane. Layout ini menyusun komponen
ke dalam 5 wilayah (region), yaitu north, south, east, west, dan center. Komponen-komponen dapat
diletakkan pada :
a.
b.
c.
Untuk lebih jelasnya, perhatikan contoh gambar tampilan BorderLayout berikut ini.
Method-method penting yang dapat digunakan pada BorderLayout adalah sebagai berikut.
a.
b.
myContainer.add(component,position)
menambahkan komponen ke layout.
Argumen component menunjukkan komponen yang ditambahkan ke layout, sedangkan argumen
position menunjukkan posisi peletakkan komponen, sebagai contoh BorderLayout.NORTH,
BorderLayout.SOUTH,
BorderLayout.EAST,
BorderLayout.WEST,
atau
BorderLayout.CENTER.
Untuk lebih memahami penggunaan BorderLayout, pelajari contoh kode program berikut ini.
Contoh 17.11
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class BorderLayoutTest extends JFrame implements ActionListener{
private JButton button[];
private String names[] = {"Hie North","Hide South", "Hide East",
"Hide West", "Hide Center"};
private BorderLayout layout;
public BorderLayoutTest(){
super ("Demonstrasi Border Layout");
layout = new BorderLayout (5,5);
Container c = getContentPane();
c.setLayout(layout);
button = new JButton[names.length];
for (int i=0 ; i < names.length; i++){
button [i] = new JButton(names[i]);
button [i].addActionListener(this);
}
206
c.add(button[0], BorderLayout.NORTH);
c.add(button[1], BorderLayout.SOUTH);
c.add(button[2], BorderLayout.EAST);
c.add(button[3], BorderLayout.WEST);
c.add(button[4], BorderLayout.CENTER);
setSize (300,200);
show();
}
public void actionPerformed(ActionEvent e){
for(int i=0; i<button.length;i++){
if(e.getSource()==button[i]) button[i].setVisible(false);
else button[i].setVisible(true);
layout.layoutContainer(getContentPane());
}
}
public static void main(String[] args) {
BorderLayoutTest app = new BorderLayoutTest();
app.addWindowListener(new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);}
});
}
}
17.23.3 GridLayout
GridLayout membagi Container ke dalam suatu grid. Komponen diletakkan dalam suatu baris
dan kolom dan memiliki ukuran lebar dan tinggi yang sama. Komponen-komponen ditambahkan mulai
dari kiri atas, selanjutnya ke kanan. Jika baris sudah penuh, maka komponen diletakkan di baris
selanjutnya, kemudian dari kiri ke kanan. Berikut contoh gambar GridLayout.
b.
Method milik container validate dapat digunakan untuk merancang ulang (update) sebuah
container yang layout-nya sudah diubah. Berikut ini penggalan kode program untuk mengubah layout
dan meng-update Container c jika memenuhi kondisi tertentu.
207
Untuk lebih memahami penggunaan GridLayout dan penggunaan method validate, pelajari
contoh kode program berikut ini.
Contoh 17.12
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class GridLayoutTest extends JFrame implements ActionListener {
private JButton button[];
private String names[] = {"Satu","Dua","Tiga","Empat","Lima","Enam"};
private boolean toggle = true;
private Container c;
private GridLayout g1, g2;
public GridLayoutTest(){
super("Demonstrasi GridLayout");
g1 = new GridLayout(2,3,5,5);
g2 = new GridLayout(3,2);
c = getContentPane();
c.setLayout(g1);
button = new JButton[names.length];
for(int i = 0; i<names.length;i++){
button[i] = new JButton(names[i]);
button[i].addActionListener(this);
c.add(button[i]);
}
setSize(300,300);
show();
}
public void actionPerformed(ActionEvent e){
if (toggle) c.setLayout(g1);
else c.setLayout(g2);
toggle =! toggle;
c.validate();
}
public static void main(String[] args) {
GridLayoutTest app = new GridLayoutTest();
app.addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);
}
}
);
}
}
17.23.4 GridBagLayout
GridBagLayout merupakan layout manager yang cukup komplek, namun powerful. Layout ini
menyusun komponen ke dalam grid sebagaimana ditunjukkan pada gambar berikut ini.
208
2.
Bagi GUI tersebut ke dalam grid mulai dari baris dan kolom 0. Hal ini dilakukan untuk
menempatkan komponen di posisi yang benar.
3.
Buat sebuah obyek GridBagConstraints. Obyek ini menentukan bagaimana komponenkomponen ditempatkan.
4.
gridx - kolom.
gridy - baris.
gridwidth - jumlah kolom yang dialokasikan.
gridheight - jumlah baris yang dialokasikan.
weightx - ukuran ruang horisontal.
weighty - ukuran ruang vertikal.
5.
6.
7.
8.
9.
Untuk lebih memahami penggunaan GridBagLayout, pelajari contoh kode program berikut ini.
Contoh 17.13
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GridBagTest extends JFrame {
private Container container;
private GridBagLayout gbLayout;
private GridBagConstraints gbConstraints;
public GridBagTest(){
super("Demonstrast GridBagLayout");
container = getContentPane();
gbLayout = new GridBagLayout();
container.setLayout(gbLayout);
gbConstraints = new GridBagConstraints();
JTextArea ta = new JTextArea("Rekayasa Industri", 5,10);
JTextArea tx = new JTextArea("Sistem Informasi",2,2);
String names[] = {"Institut", "Teknologi", "Telkom"};
JComboBox cb = new JComboBox(names);
JTextField tf = new JTextField("Center");
JButton b1 = new JButton("Java");
JButton b2 = new JButton("Competency");
JButton b3 = new JButton("Center");
209
gbConstraints.fill = GridBagConstraints.BOTH;
addComponent(ta,0,0,1,3);
gbConstraints.fill = GridBagConstraints.NONE;
addComponent(b1,0,1,2,1);
addComponent(cb,2,1,2,1);
gbConstraints.weightx=1000;
gbConstraints.weighty=1;
gbConstraints.fill = GridBagConstraints.BOTH;
addComponent(b2,1,1,1,1);
gbConstraints.weightx=0;
gbConstraints.weighty=0;
addComponent(b3,1,2,1,1);
addComponent(tf,3,0,2,1);
addComponent(tx,3,2,1,1);
setSize(300,200);
show();
}
private void addComponent(Component c, int row,int column, int w, int h){
gbConstraints.gridx = column;
gbConstraints.gridy = row;
gbConstraints.gridwidth = w;
gbConstraints.gridheight = h;
gbLayout.setConstraints(c, gbConstraints);
container.add(c);
}
public static void main(String[] args) {
GridBagTest app = new GridBagTest();
}
}
17.24 Panel
Kelas JPanel diturunkan dari JComponent. Setiap JPanel adalah Container. Pada JPanel
dapat ditambahkan beberapa komponen atau panel lain. Ukuran area JPanel diukur berdasarkan
komponen yang dicakupnya dan terus berkembang untuk mengakomodasi komponen yang
ditambahkan padanya. Berikut ini gambar JPanel.
Buat obyek panel, dan tentukan jenis layout dari panel tersebut.
Tambahkan komponen ke panel.
Tambahkan panel ke ContentPane. Nilai default-nya adalah BorderLayout.
Untuk lebih memahami penggunaan JPanel, pelajari contoh kode program berikut ini.
210
Contoh 17.14
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class PanelTest extends JFrame {
private JPanel buttonPanel;
private JButton buttons[];
public PanelTest(){
super("Demonstrasi Panel");
Container c = getContentPane();
buttonPanel = new JPanel();
buttons = new JButton[5];
buttonPanel.setLayout(new FlowLayout());
for (int i =0; i<buttons.length;i++){
buttons[i] = new JButton("Tombol " + (i + 1));
buttonPanel.add(buttons[i]);
}
c.add(buttonPanel, BorderLayout.SOUTH);
setSize(500,500);
show();
}
public static void main(String[] args) {
PanelTest app = new PanelTest();
app.addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);}
}
);
}
}
JPanel juga dapat digunakan sebagai area untuk menggambar. Sebagaimana ditunjukkan pada
gambar berikut ini.
Ada beberapa hal yang perlu diperhatikan ketika menggunakan JPanel untuk menggambar.
Mengkombinasikan Swing GUI dengan menggambar dalam satu window dapat menyebabkan error.
Oleh karena itu, dibutuhkan pemisahan GUI dengan gambar.
Method paintComponent merupakan method komponen Swing yang diturunkan dari
JComponent. Method ini digunakan untuk menggambar. Programmer harus me-override method
tersebut seperti berikut.
211
Contoh 17.15
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class CustomPanelTest extends JFrame {
private JPanel buttonPanel;
private CustomPanel myPanel;
private JButton circle, square;
public CustomPanelTest(){
super("Demonstasi CustomPanel");
myPanel = new CustomPanel();
myPanel.setBackground(Color.cyan);
square = new JButton("Bujur Sangkar");
square.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
myPanel.draw(CustomPanel.SQUARE);
}
}
);
circle = new JButton("Lingkaran");
circle.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
myPanel.draw(CustomPanel.CIRCLE);
}
}
);
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1,2));
buttonPanel.add(circle);
buttonPanel.add(square);
Container c = getContentPane();
c.add(myPanel, BorderLayout.CENTER);
c.add(buttonPanel, BorderLayout.SOUTH);
setSize(300,200);
show();
}
private class CustomPanel extends JPanel {
public final static int CIRCLE =1, SQUARE = 2;
private int shape;
public void paintComponent(Graphics g){
super.paintComponent(g);
if(shape== CIRCLE) g.fillOval(50,10,60,60);
if(shape==SQUARE) g.fillRect(50,10,60,60);
}
public void draw(int s){
shape=s;
repaint();
}
}
public static void main(String[] args) {
CustomPanelTest app = new CustomPanelTest();
}
}
212
17.25
Menu
Menu merupakan bagian penting dalam GUI. Obyek menu dipasang pada obyek kelas yang memiliki
method setJMenuBar. Menu juga mempunyai ActionEvents. Gambar berikut menunjukkan
contoh tampilan menu.
b.
JMenuItem mendefinisikan menu item. JMenuItem dapat melakukan aksi atau menjadi
submenu. Salah satu method JMenuItem adalah isSelected.
c.
JMenu mendefinisikan menu yang terdiri dari menu item, lalu menambahkannya ke dalam menu
bars. JMenu dapat ditambahkan ke menu lainnya sebagai submenu. Ketika diklik, JMenu
menunjukkan daftar menu item.
d.
Menu item dapat diakses menggunakan Mnemonics (contoh File). Method yang digunakan untuk hal
tersebut adalah sebagai berikut.
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
instansiasi obyek JMenuBar, selanjutnya kirim obyek tersebut sebagai argumen method
setJMenuBar dan tentukan mnemonics-nya;instansiasi obyek JMenu dan tentukan mnemonicnya;instansiasi obyek JMenuItem dan tentukan event handler-nya;jika menggunakan
JRadioButtonMenuItem, maka buatlah sebuah obyek ButtonGroup seperti berikut ini
:myGroup = new ButtonGroup();
lalu tambahkan JRadioButtonMenuItems ke grup tersebut;
e.
f.
Jika membuat submenu, tambahkan submenu tersebut ke menu dengan memanggil method
add(mySubMenu).
g.
Untuk lebih memahami penggunaan menu, pelajari kode program berikut ini.
213
Contoh 17.16
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MenuTest extends JFrame {
private Color warna[] = {Color.black,Color.blue,Color.red,Color.green};
private JRadioButtonMenuItem colorItems[], fonts[];
private JCheckBoxMenuItem styleItems[];
private JLabel display;
private ButtonGroup fontGroup, colorGroup;
private int style;
public MenuTest(){
super("Demonstrasi JMenus");
JMenuBar bar = new JMenuBar();
setJMenuBar(bar);
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
JMenuItem aboutItem = new JMenuItem("About..");
aboutItem.setMnemonic('A');
aboutItem.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(MenuTest.this,
"Aplikasi ini adalah contoh penggunaan
JOptionPane.PLAIN_MESSAGE);
}
});
JMenus","About",
fileMenu.add(aboutItem);
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setMnemonic('x');
exitItem.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
fileMenu.add(exitItem);
bar.add(fileMenu);
JMenu formatMenu = new JMenu("Format");
formatMenu.setMnemonic('r');
String colors[] = {"Hitam","Biru","Merah","Hijau"};
JMenu colorMenu = new JMenu("Color");
colorMenu.setMnemonic('C');
colorItems=new JRadioButtonMenuItem[colors.length];
colorGroup = new ButtonGroup();
ItemHandler itemHandler = new ItemHandler();
for(int i = 0; i<colors.length;i++){
colorItems[i] = new JRadioButtonMenuItem(colors[i]);
colorMenu.add(colorItems[i]);
colorGroup.add(colorItems[i]);
colorItems[i].addActionListener(itemHandler);
}
colorItems[0].setSelected(true);
formatMenu.add(colorMenu);
formatMenu.addSeparator();
String fontNames[] = {"TimeRoman","Courier","Helvetica"};
JMenu fontMenu = new JMenu("Font");
fontMenu.setMnemonic('n');
fonts = new JRadioButtonMenuItem[fontNames.length];
fontGroup = new ButtonGroup();
for(int i=0; i<fonts.length;i++){
fonts[i] = new JRadioButtonMenuItem(fontNames[i]);
fontMenu.add(fonts[i]);
fontGroup.add(fonts[i]);
fonts[i].addActionListener(itemHandler);
}
214
fonts[0].setSelected(true);
fontMenu.addSeparator();
String styleNames[] = {"Bold", "Italic"};
styleItems = new JCheckBoxMenuItem[styleNames.length];
StyleHandler styleHandler = new StyleHandler();
for(int i=0;i<styleNames.length;i++){
styleItems[i] = new
JCheckBoxMenuItem(styleNames[i]);
fontMenu.add(styleItems[i]);
styleItems[i].addItemListener(styleHandler);
}
formatMenu.add(fontMenu);
bar.add(formatMenu);
Icon icon = new ImageIcon("./image/logo.png");
display = new JLabel("Sample Text", SwingConstants.CENTER);
display.setIcon(icon);
display.setHorizontalTextPosition(SwingConstants.CENTER);
display.setVerticalTextPosition(SwingConstants.BOTTOM);
display.setForeground(warna[0]);
display.setFont(new Font("TimesRoman", Font.PLAIN,50));
getContentPane().setBackground(Color.white);
getContentPane().add(display, BorderLayout.CENTER);
setSize(500,500);
show();
}
public static void main(String[] args) {
MenuTest app = new MenuTest();
}
private class ItemHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
for(int i = 0;i<colorItems.length;i++)
if(colorItems[i].isSelected()) {
display.setForeground((warna[i]));
}
for(int i =0;i<fonts.length;i++)
if(e.getSource()==fonts[i]) {
display.setFont(new
Font(fonts[i].getText(), style, 50));
}
}
}
private class StyleHandler implements ItemListener{
public void itemStateChanged(ItemEvent e){
style = 0;
if(styleItems[0].isSelected())
style += Font.BOLD;
if(styleItems[1].isSelected())
style += Font.ITALIC;
display.setFont(new
Font(display.getFont().getName(),
style, 75));
repaint();
}
}
}
215
17.26
JPopupMenus
Popup menu dibuat oleh kelas JPopupMenu. JPopupMenu merupakan turunan dari JComponent.
Contoh JPopupMenu ditunjukkan pada gambar berikut.
Contoh 17.17
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class PopupTest extends JFrame {
private JRadioButtonMenuItem items[];
private Color colorValues[]={Color.blue,Color.yellow,Color.red};
public PopupTest(){
super("Demostrasi Penggunaan JPopupMenus");
final JPopupMenu popupMenu = new JPopupMenu();
ItemHandler handler = new ItemHandler();
String colors[]={"Biru", "Kuning", "Merah"};
ButtonGroup colorGroup = new ButtonGroup();
items = new JRadioButtonMenuItem[3];
for(int i = 0; i<items.length;i++){
items[i] = new JRadioButtonMenuItem(colors[i]);
popupMenu.add(items[i]);
colorGroup.add(items[i]);
items[i].addActionListener(handler);
}
216
getContentPane().setBackground(Color.gray);
addMouseListener(
new MouseAdapter(){
public void mousePressed(MouseEvent e){
checkForTriggerEvent(e);
}
public void mouseReleased(MouseEvent e) {
checkForTriggerEvent(e);
}
public void checkForTriggerEvent(MouseEvent e) {
if(e.isPopupTrigger())
popupMenu.show(e.getComponent(),e.getX(), e.getY());
}
}
);
setSize(500,500);
show();
}
public static void main(String[] args) {
PopupTest app = new PopupTest();
app.addWindowListener(
new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);}
}
);
}
private class ItemHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
for(int i=0;i<items.length;i++){
if (e.getSource()==items[i]){
getContentPane().setBackground(colorValues[i]);
repaint();
}
}
}
}
}
17.27
Multiple Document Interface (MDI) mendefinisikan parent window yang terdiri dari beberapa child
windows. MDI mengatur beberapa open document dan berpindah ke antar dokumen tanpa harus
menutupnya. Berikut contoh gambar tampilan MDI.
217
JDesktopPane digunakan untuk mengatur JInternalFrame child windows. Sama halnya dengan
JFrame, JInternalFrame memiliki contentPaint untuk meletakkan komponen.
JInternalFrame dapat ditambahkan ke JDesktopPane dengan menggunakan method
add(myframe).
theDesktop.add(frame);
Untuk lebih memahami penggunaan JDesktopPane dan JinternalFrame, pelajari kode program
berikut ini.
Contoh 17.18
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class DesktopTest extends JFrame {
public DesktopTest(){
super("Demonstrasi Penggunaan JDesktopPane");
JMenuBar bar = new JMenuBar();
JMenu addMenu = new JMenu("Add");
JMenuItem newFrame = new JMenuItem("Internal Frame");
addMenu.add(newFrame);
bar.add(addMenu);
setJMenuBar(bar);
final JDesktopPane theDesktop = new JDesktopPane();
getContentPane().add(theDesktop);
newFrame.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
MyFrame frame = new MyFrame();
theDesktop.add(frame);
}});
setSize(500,500);
show();
}
public static void main(String[] args) {
DesktopTest app = new DesktopTest();
}
private class MyFrame extends JInternalFrame{
private JTextArea t1, t2;
private JButton copy;
public MyFrame(){
super("JTextArea",true,true,true,true);
Box b = Box.createHorizontalBox();
String s = "Sistem Informasi \n Institut Teknologi Telkom;
t1 = new JTextArea(s,10,15);
b.add(new JScrollPane(t1));
copy = new JButton("Copy >>>");
copy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
t2.setText(t1.getSelectedText());
}
});
b.add(copy);
t2 = new JTextArea(10,15);
t2.setEnabled(false);
b.add(new JScrollPane(t2));
getContentPane().add(b);
setSize(500,500);
show();
}
}
}
218
7.13 JToolBar
Swing menyediakan komponen baru yang tidak disediakan oleh AWT yaitu JToolBar. Pada
dasarnya, JToolBar memiliki kesamaan fungsi dengan JPanel pengikat button kecil. Namun,
perbedaan utamanya adalah JToolBar bersifat dockable atau floatable, dimana JToolBar dapat didrag ke luar original window, sehingga menjadi standalone window. JToolBar juga dapat di-drag
kembali ke dalam window atau dipindahkan posisinya ke samping kiri, kanan, atas, atau bawah window.
Gambar berikut adalah contoh tampilan JToolbar.
Tombol pada toolbar harus lebih kecil daripada JButton biasa. Oleh karena itu, gunakan method
setMargin dengan nilai konsturktor obyek Insets nol semuanya sebagaimana ditunjukkan
pada penggalan kode program berikut ini.
Insets margins = new Insets(0, 0, 0, 0);
for(int i=0; i<toolbarLabels.length; i++) {
ToolBarButton button = new ToolBarButton("./image/" +
imageFiles[i]);
button.setToolTipText(toolbarLabels[i]);
button.setMargin(margins);
add(button);
}
b.
Pada JButton label teks disimpan di sebelah kanan icon, tetapi teks label pada toolbar disimpan
di bawah icon. Untuk itu, panggil method berikut ini.
setVerticalTextPosition(BOTTOM);
setHorizontalTextPosition(CENTER);
Untuk lebih memahami penggunaan JToolbar, pelajari contoh kode program berikut ini.
Contoh 17.19
import
import
import
import
java.awt.*;
javax.swing.*;
com.jgoodies.looks.plastic.PlasticLookAndFeel.*;
java.awt.event.*;
219
17.28
JTable
JTabel merupakan komponen untuk menampilkan data dalam tabel. Biasanya komponen ini sering
digunakan untuk menampilkan data-data yang diambil dari database. Gambar berikut memperlihatkan
contoh penggunaan JTabel.
220
Buat tabel dan model data yang akan ditampilkan di tabel. Hal ini dapat dilakukan dengan cara
membuat table dan menghubungkan model data.
JTable table = new JTable();
table.setModel (theModel);
atau lebih sederhananya sebagai berikut :
JTable table = new JTable(theModel);
2.
Jika model data berupa obyek Vector atau Obyek Array, masukkan data tersebut ke dalam
konstruktor JTable sebagaimana ditunjukkan pada penggalan koe program berikut.
Untuk lebih memahami penggunaan JTable, pelajari contoh kode program berikut ini.
Contoh 17.20
import
import
import
import
javax.swing.*;
java.awt.*;
java.awt.event.*;
java.util.*;
221
17.29
Penanganan Event
GUI merupakan event driven. GUI mengaktifkan sebuah event ketika pengguna berinteraksi dengan
GUI, sebagai contoh pengguna menggerakan mouse, mengklik mouse, mengetik suatu teks di sebuah
text field, dan lainnya. Informasi event disimpan di obyek turunan AWTEvent.
Berikut langkah-langkah untuk memproses sebuah event.
a.
yang
atau
b.
terapkan event handler. Event handler adalah method yang dipanggil untuk menghasilkan jawaban
dari event tertentu. Event handling interface mempunyai satu atau lebih method yang harus
didefinisikan.
registrasi ke event listener. JComponent memiliki daftar event listener yang disebut
listenerList. Ketika text1.addActionListener(handler) dijalankan, daftar event
listener disimpan di listenerList.
b.
menangani event. Ketika event muncul, event tersebut memiliki event ID. ID ini digunakan untuk
menentukan method mana yang harus dipanggil. Jika event berupa ActionEvent, maka method
actionPerformed yang akan dipanggil.
b.
public
public
public
public
public
void
void
void
void
void
mousePressed(MouseEvent e)
mouseClicked( MouseEvent e )
mouseReleased( MouseEvent e )
mouseEntered( MouseEvent e )
mouseExited( MouseEvent e )
Untuk lebih memahami penggunaan mouse event, pelajari contoh program berikut ini.
222
Contoh 17.21
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class MouseTracker extends JFrame implements MouseListener,MouseMotionListener{
private JLabel statusBar;
public MouseTracker(){
super("Demonstrasi Mouse Events");
statusBar = new JLabel();
getContentPane().add(statusBar, BorderLayout.SOUTH);
addMouseListener(this);
addMouseMotionListener(this);
setSize(300,300);
show();
}
public void mouseClicked(MouseEvent e){
statusBar.setText("di-Klik pada posisi:("+e.getX() +","+ e.getY() + ")");
}
public void mousePressed(MouseEvent e){
statusBar.setText("ditekan pada posisi:(" +e.getX() +"," +e.getY()+ ")");
}
public void mouseReleased(MouseEvent e){
statusBar.setText("dilepas pada posisi: (" +e.getX()+ ","+e.getY()+ ")");
}
public void mouseEntered(MouseEvent e){
statusBar.setText("Mouse di dalam Window");
}
public void mouseExited(MouseEvent e){
statusBar.setText("Mouse di luar Window");
}
public void mouseDragged(MouseEvent e){
statusBar.setText("di-drag pada posisi: ("+ e.getX()+ ","+e.getY()+ ")");
}
public void mouseMoved(MouseEvent e){
statusBar.setText("digerakkan pada posisi:("+e.getX()+","+e.getY()+ ")");
}
public static void main(String[] args) {
MouseTracker app = new MouseTracker();
app.addWindowListener(new WindowAdapter(){
public void windowsClosing(WindowEvent e){
System.exit(0);
}
}
);
}
}
223
Tabel 17.1
Daftar Kelas Adapter
Interface
Kelas Adafter
ComponentListener
ContainerListener
FocusListener
KeyListener
MouseListener
MouseMotionListener
WindowListener
ComponentAdapter
ContainerAdapter
FocusAdapter
KeyAdapter
MouseAdapter
MouseMotionAdapter
WindowAdapter
Pada kode di atas, terdapat sebuah kelas bernama anonymous inner class yang memperluas (extend)
MouseMotionAdapter yang sebenarnya mengimplementasikan MouseMotionListener. Inner
class tersebut mengambil implementasi default (empty body) method mouseDragged. Method
tersebut dapat di-override sesuai dengan kebutuhan.
Perhatikan juga penggalan kode di bawah ini :
Painter apps = new Painter();
apps.addWindowListener(
new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
);
Penggalan kode di atas digunakan pada sebuah aplikasi yang memperluas (extend) JFrame. Interface
WindowListener mendefinisikan tujuh method. WindowAdapter mendefinisikan method-method
tersebut. Pada kasus di atas, method windowClosing di-override untuk mengaktifkan tombol close.
Untuk lebih memahami penggunaan kelas Adapter, pelajari contoh kode program berikut ini.
Contoh 17.22
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Painter extends JFrame {
private int xValue = -10, yValue = -10;
public Painter(){
super("Contoh program menggambar");
getContentPane().add(new Label("Drag Mouse"),BorderLayout.SOUTH);
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
xValue = e.getX();
yValue = e.getY();
repaint();
}
});
setSize(500,500);
show();
}
224
Kelas MouseEvent merupakan turunan dari InputEvent. Kelas ini dapat membedakan antara
tombol-tombol pada multi-button mouse dan kombinasi mouse click dan keystroke. Java
mengasumsikan bahwa setiap mouse memiliki tombol kiri.
Alt + click = tombol mouse tengah
Meta + click = tombol mouse kanan
Method getClickCount mengembalikan jumlah klik yang dilakukan pengguna pada mouse. Method
isAltDown dan isMetaDown mengembalikan nilai true jika tombol mouse tengah atau tombol
mouse kanan diklik. Untuk lebih jelasnya pelajari kode program berikut.
Contoh 17.23
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MouseDetail extends JFrame{
private String s="";
private int xPos, yPos;
public MouseDetail(){
super("Mouse Clicks and Button");
addMouseListener(new MouseClickHandler());
setSize(300,300);
show();
}
public void paint (Graphics g){
g.drawString("di-Klik pada posisi:(" +xPos+","+ yPos + ")", xPos, yPos);
}
public static void main(String[] args) {
MouseDetail app = new MouseDetail();
}
225
17.4.3
Interface KeyListener menangani key events (keys pressed pada keyboard). Interface ini mendefinisikan
method berikut :
a.
b.
c.
Setiap method mengambil KeyEvent sebagai argumennya. KeyEvent ini merupakan subclass dari
InputEvent. Method-method KeyEvent adalah sebagai berikut :
a.
b.
c.
d.
e.
f.
getKeyCode mengambil kode key. Setiap key direpresentasikan dengan kode virtual key.
getKeyText mengambil konstanta kode key dan mengembalikan nama key.
getKeyChar mengambil karakter unicode dari key yang ditekan.
isActionKey mengembalikan nilai true jika key berupa action key.
getModifiers mengembalikan modifiers yang ditekan.
getKeyModifierText mengembalikan nama modifier keys dengan tipe String.
Contoh 17.24
import javax.swing.*;
import java.awt.event.*;
public class KeyDemo extends JFrame implements KeyListener {
private String line1 ="", line2="", line3="";
private JTextArea textArea;
public KeyDemo(){
super("Demonstrasi KEyborad event");
textArea = new JTextArea(10,20);
textArea.setText("Tekan tombol di keyboard");
textArea.setEnabled(false);
addKeyListener(this);
getContentPane().add(textArea);
setSize(350,100);
show();
}
public void keyPressed(KeyEvent e){
line1 = "Key pressed: " + KeyEvent.getKeyText( e.getKeyCode() );
setLines2and3( e );
}
public void keyReleased(KeyEvent e){
line1 = "Key Release: " + KeyEvent.getKeyText( e.getKeyCode() );
setLines2and3( e );
}
public void keyTyped(KeyEvent e){
line1 = "Key Typed: " + e.getKeyChar();
setLines2and3( e );
}
private void setLines2and3( KeyEvent e ){
line2 = "This key is " + (e.isActionKey()?"":"not ") + "an action key";
String temp = KeyEvent.getKeyModifiersText( e.getModifiers() );
line3 = "Modifier keys pressed: " + ( temp.equals( "" ) ? "none" : temp );
textArea.setText(line1+"\n"+line2+"\n" + line3 + "\n" );
}
public static void main( String args[] ){
KeyDemo app = new KeyDemo();
}
}
226
18
Java menyediakan sebuah antarmuka untuk melakukan operasi-operasi pada database. Antarmuka ini
disebut Java Database Connectivity (JDBC). Paket Java Software Development Kit menyediakan JDBC ini
dalam dua package yaitu java.sql (biasanya disebut core API) dan javax.sql (biasanya disebut
Optional package API). Dalam package tersebut didefinisikan sejumlah kelas yang memfasilitasi
pengiriman pernyataan SQL ke database dengan berbagai dialek SQL.
Meskipun sudah ada kedua package tersebut untuk menggunakan JDBC, masih diperlukan suatu
pustaka lagi dari vendor pembuat Database Management System (DBMS). Fungsi dari pustaka
tambahan ini adalah sebagai driver penghubung antara DBMS yang digunakan dengan aplikasi Java.
Pustaka ini biasanya bisa didownload secara gratis pada situs resmi vendor pembuat DBMS.
Pemrograman database dengan Java selalu melibatkan JDBC. JDBC ini menggunakan driver yang
disediakan oleh vendor DBMS untuk melakukan operasi database pada DBMS. Driver ini berbentuk file
Java Archive (JAR) yang harus kita masukkan dalam CLASSPATH aplikasi Java. Terkadang driver untuk
DBMS ini lebih dari satu file JAR. Sebaiknya semua file JAR dimasukkan supaya nantinya tidak ditemui
kesulitan jika aplikasi akan menggunakan fitur-fitur khusus secara spesifik yang dimiliki oleh DBMS
tertentu. Driver JDBC ini melakukan tiga hal dibawah ini:
1.
2.
3.
Berikut contoh penggalan kode program yang membangun koneksi dengan database, mengirim query
dan memperbaharui data, dan memproses hasil query.
Sesuai contoh penggalan program di atas, pemrograman yang melibatkan database di Java memerlukan
beberapa tahap yaitu:
1.
2.
3.
4.
Pada banyak aplikasi database biasanya digunakan methode Connection Pooling untuk melakukan
koneksi ke database. Methode ini dinilai efektif karena untuk modul-modul dari aplikasi yang ingin
menggunakan database tidak perlu membuat koneksinya sendiri-sendiri tetapi menggunakan satu
koneksi yang telah terbentuk dan dipakai bersama-sama secara bergantian. Pustaka untuk melakukan
connection pooling ini bisa didapatkan dari Apache atau dapat dibuat sendiri oleh programmer
sebagaimana ditunjukkan pada contoh kode program berikut ini.
227
Contoh 18.1
import
import
import
import
import
import
import
import
java.sql.Connection;
java.sql.DriverManager;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
java.util.ArrayList;
java.util.List;
java.util.Properties;
228
18.7
Menggunakan Connection
Obyek Connection adalah yang pertama kali harus terbentuk sebelum melakukan operasi database.
Obyek Connection merepresentasikan koneksi dengan database yang dibentuk. Sebelum obyek
Connection dibentuk, driver untuk DBMS yang bersangkutan perlu di-load terlebih dahulu dengan
menggunakan kelas Connection yang dibentuk dengan menggunakan DriverManager.
229
Proses loading driver DBMS ke dalam aplikasi Java kita sangat mudah dan dapat dilakukan dengan satu
baris kode. Proses ini melibatkan Reflection API yaitu pembentukan obyek berdasarkan nama kelasnya
yang berupa String. Mengenai nama kelas yang harus di load bervariasi tergantung pada driver
DBMS yang digunakan. Baca manual driver yang biasanya disertakan dalam driver DBMS untuk JDBC.
Karena mengggunakan Reflection API, proses loading memungkinkan terjadinya exception yaitu
ClassNotFoundException. Berikut potongan kode untuk melakukan loading kelas driver JDBC:
try {
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
} catch(java.lang.ClassNotFoundException e) {
System.err.println(e.getMessage());
}
Selanjutnya setelah driver berhasil di-load Connection bisa dibentuk dengan menggunakan
DriverManager. Connection dibentuk dengan memanggil method getConnection pada
DriverManager. Method ini mempunyai argumen url yang mengidentifikasi alamat database
server , nama database, nama pengguna database, dan password.
URL yang menunjukkan lokasi database server didefinisikan dengan format yang berbeda dengan
format URL pada internet. Format URL untuk masing-masing jenis DBMS dapat berbeda-beda. Cara
penulisan ini sudah ditentukan sendiri oleh pembuat driver JDBC sehingga programmer tidak perlu
membuat sendiri. Dalam URL ini tercantum nama komputer atau IP address lokasi komputer berada
beserta dengan port yang digunakan untuk berkomunikasi dengan database server. Pada beberapa
DBMS seperti Microsoft SQL Server nama database, nama user, dan password dapat dimasukkan pada
URL ini. Secara umum format JDBC URL terdiri dari tiga bagian yaitu protokol, subprotokol dan
subnama.
<protocol>:<subprotocol>:<subname>
Protokol disini selalu berisi jdbc. Subprotokol merupakan nama driver atau mekanisme koneksi yang
digunakan. Subprotokol ini terdiri dari satu atau dua elemen tergantung spesifikasi dari driver yang
digunakan, tetapi biasanya terdiri dari dua elemen. Contohnya, seperti yang digunakan oleh SQL Server
yaitu microsoft:sqlserver. Subnama merupakan bagian untuk mengidentifikasikan data source.
Format subnama bisa beragam tergantung dari driver yang digunakan. Data source yang terletak di
komputer terpisah dalam suatu jaringan diperlukan tambahan informasi menyangkut nama atau IP
address dan port komputer data source.
18.8
Menggunakan Statement
Setelah obyek Connection ini terbentuk obyek Statement selanjutnya dibentuk untuk melakukan
operasi database. Statement dibuat dengan menggunakan method createStatement yang
terdapat pada obyek Connection. Statement merupakan obyek yang digunakan untuk mengirim
pernyataan SQL ke database.
Statement merupakan interface yang memiliki dua interface sebagai turunannya yaitu
PreparedStatement dan CallableStatement. Statement digunakan untuk mengeksekusi
SQL yang sederhana. PreparedStatement digunakan untuk mengeksekusi SQL yang precompiled.
CallableStatement digunakan untuk memanggil stored procedure yang terdapat dalam database.
230
Statement mempunyai dua method yang digunakan untuk mengeksekusi SQL yaitu executeQuery
dan executeUpdate. Method executeQuery digunakan untuk mengeksekusi SQL yang
memberikan kembalian berupa data dari database (perintah SELECT). Data ini nantinya akan diambil
oleh ResultSet. Sedangkan method executeUpdate digunakan untuk mengeksekusi SQL yang
tidak memerlukan kembalian dari database (INSERT, UPDATE dan DELETE).
PreparedStatement berisi SQL yang sebelumnya sudah terkompilasi. Maksud terkompilasi di sini
adalah sudah didefinisikan sebelumnya dan hanya tinggal mengisi parameter-parameter SQL yang
dibutuhkan. Selanjutnya baru dimasukkan parameter-parameter yang dibutuhkan untuk kemudian
dieksekusi. SQL yang dapat digunakan dalam PreparedStatement disini berupa SELECT, INSERT
UPDATE dan DELETE. PreparedStatement juga memiliki method executeUpdate dan
executeQuery yang penggunaannya tergantung dari jenis SQL yang dieksekusi. Contoh inisiasi,
pengisian parameter dan eksekusi dari PreparedStatement bisa dilihat pada Tabel 18.1.
CallableStatement digunakan untuk memanggil stored procedure yang sebelumnya telah
didefinisikan dalam database. Pendefinisian stored procedure ini dapat langsung pada database
maupun melalui Statement. Untuk eksekusi dari CallableStatement sama seperti pada
Statement yaitu menggunakan method executeQuery atau executeUpdate tergantung pada
stored procedure yang dipanggil.
Statement dan turunannya, PreparedStatement dan CallableStatement, dibentuk
melalui pemanggilan method bukan statik yang terdapat pada obyek Connection. Oleh karena itu
obyek Connection harus terlebih dahulu dibentuk. Statement dibentuk melalui pemanggilan
method createStatement. PreparedStatement dibentuk melalui pemanggilan method
prepareStatement. CallableStatement dibentuk melalui pemanggilan method
prepareCall.
TABEL 18.1
Contoh inisiasi, pengisian parameter, dan eksekusi Statement, PreparedStatement, dan
CallableStatement
Menggunakan
Statment
Menggunakan
PreparedStatement
Menggunakan
CallableStatement
Pada beberapa potongan kode di Tabel 18.1 atas diberikan contoh pembentukan Obyek Statement,
PreparedStatement dan CallableStatement beserta penggunaannya. Pada Statement
terlihat bahwa String yang merupakan SQL yang sudah jadi dan siap dikirimkan langsung ke database
untuk di eksekusi.
Pada contoh PreparedStatement, SQL yang menjadi parameter dari method
prepareStatement merupakan SQL yang belum lengkap / precompiled ditandai dengan tanda
tanya (?) dalam String. Pada baris berikutnya baru dilakukan operasi untuk mengisi parameterparameter yang dibutuhkan tersebut. Setelah semua parameter berhasil diisikan barulah SQL dapat
dieksekusi.
Untuk contoh CallableStatement, tidak ada pernyataan SQL. Hal ini dikarenakan pernyataan SQL
sudah masuk dalam pendefinisian stored procedure sebelumnya. CallableStatement hanya
memanggil stored procedure yang telah terbentuk dengan memasukkan String {call
nama_stored_procedure}.
231
18.9
Menggunakan ResultSet
ResultSet adalah sebuah interface yang digunakan untuk menampung data kembalian dari operasi
SQL. ResultSet merupakan tipe kembalian dari pemanggilan method executeQuery. Method
executeQuery mengeksekusi SQL jenis SELECT yang mengembalikan sejumlah baris data yang
ditampung dalam ResultSet.
Setelah ResultSet diperoleh sebagai kembalian dari method executeQuery, hasil dari data ini
dapat dimanfaatkan. Kumpulan data di dalam ResultSet tidak dapat di query lagi sehingga biasanya
pada pemanfaatannya menggunakan iterasi untuk mencari data mana yang tepat atau memproses
seluruh data. Untuk melakukan iterasi tiap-tiap baris data dalam ResultSet digunakan method
next. Method next ini menggerakkan cursor pada ResultSet untuk menunjuk pada baris data
selanjutnya.
Pada penggalan kode di atas ditunjukkan cara untuk mengambil hasil query dengan ResultSet.
Selain itu ditunjukkan cara iterasi untuk melihat isi baris data yang terdapat pada ResultSet. Untuk
mendapatkan nilai dari masing-masing field dalam baris, ResultSet menyediakan method getXXX
yang memungkinkan untuk mengambil nilai tersebut sesuai dengan tipe datanya apakah itu String,
int, float dan sebagainya. Method getXXX ini memerlukan parameter berupa String yang
merupakan nama dari kolom tabel di database. Pada contoh diatas ditunjukkan method getString
dan getFloat.
Salah satu interface turunan dari ResultSet adalah RowSet. Semua sifat-sifat yang dimiliki oleh
ResultSet dimiliki juga oleh RowSet. RowSet juga menampung data yang didapatkan dari operasi
query. RowSet memiliki sifat-sifat sama seperti komponen JavaBean. RowSet memungkinkan
pengubahan data yang terdapat di dalamnya dan melakukan propagasi balik ke database atas data yang
diperbaharui. RowSet biasanya diimplementasikan oleh vendor JDBC driver. Spesifikasi untuk RowSet
ini tertuang dalam JSR 114.
232
TABEL 18.2
Contoh Penggunaan Batch Menggunakan Statement dan PreparedStatement
Menggunakan
Statement
con.setAutoCommit(false);
Statement stmt = con.createStatement();
stmt.addBatch("INSERT INTO COFFEES " +
"VALUES('Amaretto', 49, 9.99, 0, 0)");
stmt.addBatch("INSERT INTO COFFEES " +
"VALUES('Hazelnut', 49, 9.99, 0, 0)");
stmt.addBatch("INSERT INTO COFFEES " +
"VALUES('Amaretto_2',49,10.99,0, 0)");
stmt.addBatch("INSERT INTO COFFEES " +
"VALUES('Hazelnut_2',49,10.99,0,0)");
int [] updateCounts = stmt.executeBatch();
con.commit();
con.setAutoCommit(true);
Menggunakan
PreparedStatement
con.setAutoCommit(false);
PreparedStatement pstmt = con.prepareStatement(
"INSERT INTO COFFEES VALUES(?, ?, ?, ?, ?)");
pstmt.setString(1, "Amaretto");
pstmt.setInt(2, 49);
pstmt.setFloat(3, 9.99);
pstmt.setInt(4, 0);
pstmt.setInt(5, 0);
pstmt.addBatch();
pstmt.setString(1, "Hazelnut");
pstmt.setInt(2, 49);
pstmt.setFloat(3, 9.99);
pstmt.setInt(4, 0);
pstmt.setInt(5, 0);
pstmt.addBatch();
int [] updateCounts = stmt.executeBatch();
con.commit();
con.setAutoCommit(true);
Pada potongan kode diatas tampak bahwa fitur auto commit pada database dimatikan terlebih dahulu
sebelum memulai proses batch. Auto commit dimatikan dengan memanggil method setAutoCommit
dengan parameter false. Hal ini ditujukan agar setelah method executeBatch dipanggil perubahan
data pada database yang terjadi tidak dilakukan setelah suatu SQL dibaca tetapi di eksekusi sekaligus
setelah seluruh SQL dibaca di database. Mematikan auto commit akan mempermudah melakukan
debugging jika terjadi error. Berikut ini adalah contoh program yang menggunakan proses batch.
Contoh 18.2
import java.sql.*;
public class BatchUpdate {
public static void main(String args[]) {
String url = "jdbc:mySubprotocol:myDataSource";
Connection con;
Statement stmt;
try {
Class.forName("myDriver.ClassName");
} catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try {
con = DriverManager.getConnection(url,
con.setAutoCommit(false);
stmt = con.createStatement();
stmt.addBatch("INSERT INTO COFFEES " +
stmt.addBatch("INSERT INTO COFFEES " +
stmt.addBatch("INSERT INTO COFFEES " +
"myLogin", "myPassword");
233
18.11 Transaksi
Adakalanya pada saat proses batch terjadi masalah pada sistem yang menyebabkan proses batch
dihentikan. Hal ini menyebabkan sebagian data berhasil diperbaharui ke database sedangkan sebagian
lainnya tidak berhasil diperbaharui sehingga data yang tersimpan di database menjadi tidak konsisten.
Untuk mengatasi masalah ini, deperlukan suatu mekanisme yang disebut transaction atau transaksi.
Transaksi memungkinkan perubahan pada database, baik berupa INSERT, DELETE, dan UPDATE dapat
dibatalkan pada saat proses batch sedang berlangsung. Pernyataan SQL yang sudah terlanjur dieksekusi
ke dalam database secara otomatis akan dibatalkan atau di-rollback. Mekanisme transaksi ini dimiliki
oleh interface Connection melalui pemanggilan method rollback().
Sebelum mengaktifkan mekanisme transaksi terlebih dahulu harus mengubah mode auto commit
menjadi false melalu pemanggilan method setAutoCommit(boolean mode). Jika method ini
diset nilainya menjadi true, maka setiap pernyataan SQL akan dieksekusi satu persatu, namun jika
method ini diset menjadi false maka beberapa pernyataan SQL dieksekusi secara serentak.
Method commit() milik interface Connection menyebabkan proses batch atau eksekusi SQL
diterapkan ke database sehingga database memperbaharui data-data sesuai dengan pernyataan SQL
yang diterimanya. Jika terjadi masalah selama proses eksekusi batch atau pernyataan SQL, method
rollback() sebaiknya dipanggil untuk membatalkan proses eksekusi dan mengembalikan status
database ke sebelumnya. Method getAutoCommit() mengembalikan status auto commit, true atau
false.
Penggalan kode program pada Contoh 18.1 berikut ini menunjukkan proses transaksi sebagaimana
dijelaskan di atas
234
Tabel Author memiliki kolom memiliki kolom-kolom AuthorID (Number), FirstName (Text),
LastName (Text), dan YearBorn (Number). Berikut contoh tampilan data yang dimasukkan ke
dalamnya.
235
Tabel Publisher terdiri dari dua kolom PubliserID (Number) dan PublisherName (Text).
Berikut contoh tampilan data yang dimasukkan ke dalamnya.
Tabel AuthorISBN terdiri dari dua kolom ISBN (Text) dan AuthorID (Number). Berikut contoh
tampilan data yang dimasukkan ke dalamnya.
Tabel Titles terdiri dari dua kolom ISBN (Text) dan Title (Text), EditionNumber (Number),
YearPublished (Number), Description (Text), dan PublisherID (Number). Berikut
contoh tampilan data yang dimasukkan ke dalamnya.
236
Contoh pertama pada studi kasus ini adalah aplikasi yang melakukan query ke database book.mdb.
Aplikasi ini hanya menampilkan data-data sebagaimana ditunjukkan pada gambar berikut ini.
Contoh 18.3
import
import
import
import
import
java.sql.*;
javax.swing.*;
java.awt.*;
java.awt.event.*;
java.util.*;
237
238
EKSPERIMEN
1.
2.
Tulis kode program sebagaimana ditunjukkan pada Contoh 18.3 di atas dengan
menggunakan text editor atau editor lainnya. Simpan kode tersebut menjadi file
TableDisplay.java, lalu kompilasi program tersebut, lalu jalankan. Apa yang terjadi ?
3.
Pelajari dan analisis setiap baris kode program pada Contoh 18.3 atas ! Bila perlu setiap
baris kode program di atas diberi komentar Anda !
4.
Buatlah database book ke database server seperti Microsoft SQL Server, MySQL atau
lainnya. Ubah koneksi database yang tertulis di contoh kode program di atas ke database
server tersebut !
Studi kasus selanjutnya adalah memodifikasi program pada Contoh 18.3 dengan penambahan
komponen Graphical User Interface berupa Button dan TextArea sebagaimana ditunjukkan pada
gambar berikut ini.
Contoh 18.4
import
import
import
import
import
java.sql.*;
javax.swing.*;
java.awt.*;
java.awt.event.*;
java.util.*;
239
try {
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
connection = DriverManager.getConnection(url,username,password);
} catch ( ClassNotFoundException cnfex ) {
System.err.println( "Failed to load JDBC/ODBC driver." );
cnfex.printStackTrace();
System.exit( 1 );
} catch ( SQLException sqlex ) {
System.err.println( "Unable to connect" );
sqlex.printStackTrace();
System.exit( 1 );
}
inputQuery = new JTextArea( "SELECT * FROM Authors", 4, 30 );
submitQuery = new JButton( "Submit query" );
submitQuery.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent e ) {
if ( e.getSource() == submitQuery )
getTable();
}
}
);
JPanel topPanel = new JPanel();
topPanel.setLayout( new BorderLayout() );
topPanel.add( new JScrollPane( inputQuery),BorderLayout.CENTER );
topPanel.add( submitQuery, BorderLayout.SOUTH );
table = new JTable( 4, 4 );
Container c = getContentPane();
c.setLayout( new BorderLayout() );
c.add( topPanel, BorderLayout.NORTH );
c.add( table, BorderLayout.CENTER );
getTable();
setSize( 450, 150 );
show();
}
private void getTable(){
try {
String query = inputQuery.getText();
statement = connection.createStatement();
resultSet = statement.executeQuery( query );
displayResultSet( resultSet );
} catch ( SQLException sqlex ) {
sqlex.printStackTrace();
}
}
private void displayResultSet( ResultSet rs ) throws SQLException{
boolean moreRecords = rs.next();
if ( ! moreRecords ) {
JOptionPane.showMessageDialog(this,
"ResultSet contained no records" );
setTitle( "No records to display" );
return;
}
Vector columnHeads = new Vector();
Vector rows = new Vector();
try {
ResultSetMetaData rsmd = rs.getMetaData();
for ( int i = 1; i <= rsmd.getColumnCount(); ++i )
columnHeads.addElement( rsmd.getColumnName( i ) );
do {
rows.addElement( getNextRow( rs, rsmd ) );
} while ( rs.next() );
table = new JTable( rows, columnHeads );
JScrollPane scroller = new JScrollPane( table );
Container c = getContentPane();
c.remove( 1 );
c.add(scroller, BorderLayout.CENTER );
c.validate();
} catch ( SQLException sqlex ) {
sqlex.printStackTrace();
}
}
240
EKSPERIMEN
5.
Tulis kode program sebagaimana ditunjukkan pada Contoh 18.4 di atas dengan menggunakan
text
editor
atau
editor
lainnya.
Simpan
kode
tersebut
menjadi
file
DisplayQueryResults.java, lalu kompilasi program tersebut, lalu jalankan. Apa yang
terjadi ?
6.
Pelajari dan analisis setiap baris kode program pada Contoh 18.4 atas ! Bila perlu setiap baris
kode program di atas diberi komentar Anda !
241
242
LAMPIRAN A
PRAKTIKUM - 1
1.
Anda diminta untuk menjadi konsultan di suatu Badan Liga Sepak bola. Badan Liga Sepakbola
tersebut meminta Anda untuk membuat aplikasi pencatatan pertandingan pada suatu liga
sepakbola. Aplikasi harus mencatat sebagai berikut :
Lakukan analisis berorientasi obyek dengan membuat daftar obyek yang kemungkinan besar
digunakan dalam aplikasi tersebut, beserta atribut dan operasi yang dapat dilakukan oleh setiap
obyek tersebut, dan buat disain kelasnya secara lengkap !
2.
3.
Pada Praktikum ini, Anda harus mengkompilasi dan menjalankan sebuah kelas Customer dengan
beberapa variabel. Ikuti langkah-langkah berikut ini.
Pada file Customer.java deklarasikan beberapa variabel berikut dengan nilai default
4.
CustomerID.
CustomerStatus (nilai 'N' untuk customer baru dan 'O' untuk customer lama).
Jumlah pembelian dalam setahun.
Kompilasi dan jalankan program tersebut dan cek keluaran dari program tersebut !
Buatlah sebuah program Java untuk menghitung umur dalam menit dan milidetik. Ikutilah langkahlangkah berikut untuk menulis sebuah kelas Person yang menghitung berbagai umur :
Tambahkan sebuah method untuk menghitung dan mencetak umur seseorang dalam
menit !
Tambahkan sebuah method untuk menghitung dan mencetak umur seseorang dalam
milidetik !
Uji program yang dibuat oleh kelas bernama PersonTest dengan nilai umur 1, 24, atau 100
tahun !
243
5.
Buatlah program Java sederhana yang memanfaatkan casting untuk menjamin bahwa data yang
hilang tidak muncul pada program tersebut. Ikuti langkah-langkah berikut ini.
Tulis sebuah kelas bernama Order yang terdiri dari dua variabel bertipe int bernama
itemQuantity dan sebuah method bernama calculateTotal !
Tulis sebuah method calculateTotal yang mengalikan dua buah nilai int dan
menampilkan hasilnya !
Tes program tersebut menggunakan kelas OrderTest dengan nilai masukan 1-digit tipe
int, 5-digit tipe int, dan 9-digit tipe int !
6.
Buatlah sebuah kelas bernama Temperature yang terdiri dari variabel temperature dalam
Fahrenheit dan sebuah method bernama calculateCelsius. Method tersebut mengkonversi
temperature dalam Fahrenheit ke Celcius. Catatan, untuk konversi dari Fahrenheit ke Celsius,
kurangi dengan 32, kalikan dengan 5, dan bagi dengan 9. Tes program tersebut dengan kelas
TemperatureTest !
7.
Buatlah sebuah program Java kalkulator sederhana di mana di dalamnya terdapat operasi
matematika seperti
244
Konversi bilangan desimal ke biner atau sebaliknya, konversi bilangan desimal ke oktal atau
sebaliknya, dan konversi bilangan heksadesimal ke desimal atau sebaliknya !
LAMPIRAN B
PRAKTIKUM - 2
1.
Buatlah sebuah kelas bernama Customer. Kelas ini mempunyai tujuh variable : customerID,
nama, alamat, nomorTelepon, alamatEmail, status, dan totalPenjualan. Kelas
ini memliki method untuk menampilkan informasi tentang customer bernama
displayCustomerInfo. Ikuti langkah berikut untuk membuat kelas ini.
a.
Buat kelas yang memiliki method main untuk menguji kelas Customer !
b.
Buatkan sebuah variabel referensi obyek yang merujuk pada sebuah instance dari
kelas Customer !
Set nilai customerID dengan sebuah integer !
Set nilai status ke 'O' untuk status lama !
Set totalPenjualan ke 100.00 !
Panggil method displayCustomerInfo milik kelas Customer !
2.
Buatlah sebuah kelas bernama PersonTwo yang membuat, menginisialisasi dua buah variabel
String, dan menampilkan nilainya. Ikuti langkah berikut ini.
a.
Buatlah kelas bernama PersonTwo yang membuat dan menginisialisasi dua variabel :
-
3.
4.
c.
Buatlah sebuah method bernama displayQuote untuk menampilkan kuota dan nama
di layar !
d.
Kompilasi kelas tersebut, dan tes kelas tersebut dengan kelas PersonTwoTest.
Pada Praktikum ini Anda diminta untuk membuat sebuah kelas bernama DateTwo yang di
dalamnya menggunakan pernyataan if/else untuk menampilkan hari dalam suatu minggu
(senin s.d minggu). Ikuti langkah-langkah berikut.
a.
Buatlah sebuah kelas bernama DateTwo dengan satu variabel yang nilainya 1 sampai dengan
7 dimana nomor 1 menunjukkan hari Senin dan nomor 7 menunjukkan hari minggu !
b.
Pada kelas DateTwo, buatkan suatu method displayDay yang menggunakan pernyataan
if/else untuk megidentifikasi nomor masukan dan menentukan hari dari nomor tersebut !
c.
Method tersebut juga harus menampilkan pesan error jika nilai yang dimasukkan tidak valid !
d.
e.
Pada Praktikum ini Anda diminta mengerjakan hal serupa dengan nomor 3, namun dengan
menggunakan pernyataan switch. Ganti nama kelasnya menjadi DateThree dan kelas tesnya
dengan nama DateThreeTest !
245
5.
Pada Praktikum ini Anda diminta untuk membuat kelas yang menghitung penjumlahan dari 1
sampai angka tertentu ( 1 + 2 + 3 ..... + n). Ikuti langkah berikut ini.
a.
b.
6.
Buat sebuah kelas bernama Counter yang terdiri dari sebuah method bernama
displayCount yang melakukan sebagai berikut.
-
Kompilasi program Anda dan test program tersebut dengan kelas CounterTest.
Pada Praktikum ini Anda diminta untuk menulis sebuah kelas bernama Sequence yang
menampilkan urutan bilangan yang membentuk pola sebuah deret sebagai berikut :
1 1 2 3 5 8 13 ........
Gunakan pernyataan pengulangan while untuk program tersebut. Kompilasi program dan tes
dengan menggunakan kelas sequenceTest !
7.
Pada Praktikum ini Anda diminta mengerjakan hal serupa dengan nomor 5, namun dengan
menggunakan pernyataan pengulangan for dan do/while. Ganti nama kelasnya menjadi
CounterTwo (untuk pengulangan for), CounterThree (Untuk pengulangan do/while),
kelas tesnya dengan nama CounterTwoTest
(untuk pengulangan for), dan
CounterThreeTest (untuk pengulangan do/while) !
8.
Pada Praktikum ini Anda diminta mengerjakan hal serupa dengan nomor 6, namun dengan
menggunakan pernyataan pengulangan for dan do/while. Ganti nama kelasnya menjadi
SequenceTwo
(untuk pengulangan for), SequenceThree (Untuk pengulangan
do/while), kelas tesnya dengan nama SequenceTwoTest (untuk pengulangan for), dan
SequenceThreeTest (untuk pengulangan do/while) !
246
LAMPIRAN C
PRAKTIKUM - 3
1.
Pada Praktikum ini Anda diminta untuk menguji kelas yang menambah berbagai obyek Shirt
kepada obyek Order dan menampilkan total biaya dalam rupiah untuk setiap order. Ikuti langkah
berikut ini.
a.
Buat kelas bernama Order dan Shirt. Tuliskan atribut/variabel dan method yang perlu
ditambahkan pada kelas tersebut. Sebagai contoh variabel price pada kelas Shirt !
b.
Buat kelas bernama OrderTest dimana memiliki method main. Di dalam method main
tersebut
-
2.
c.
Buat obyek Shirt lain dan set nilai price, dan tambahkan ke dalam obyek Order !
d.
Pada Praktikum ini Anda diminta untuk membuat sebuah kelas dengan mehtod overload. Ikuti
langkah berikut ini.
a.
b.
c.
3.
method ini menambahkan sebuah Shirt ke dalam daftar Shirt yang akan
diorder di kelas Order (mirip shopping chart). parameter s merupakan referensi
obyek ke obyek Shirt. Method ini mengembalikan nilai harga
(tipe double) yang harus dibayarkan untuk order sebuah shirt.
Tampilkan total biaya yang harus dibayarkan !
Pada Praktikum ini, Anda diminta untuk membuat kelas terenkapsulasi yang terdiri dari atribut
private dan method getter dan setter. Ikuti langkah berikut ini.
a.
Buat sebuah kelas bernama DateOne yang terdiri tiga atribut integer seperti day, month,
dan year.
-
247
b.
c.
d.
Buat sebuah kelas mirip kelas DateOne bernama DateTwo. Buat atribut di kelas DateTwo
private !
e.
Buat kelas mirip DateOneTest bernama DateTwoTest. Buat referensi obyek yang
merujuk ke kelas DateTwo. Kompilasi dan jalankan kelas tersebut. Apa yang terjadi ? Analisis
hasil yang diperoleh !
f.
g.
Di kelas DateThree tambahkan method getter dan setter untuk setiap atribut kelas.
h.
i.
Buat kelas mirip DateTwoTest bernama DateThreeTest. Buat referensi obyek yang
merujuk ke kelas DateThree. Kompilasi dan jalankan kelas tersebut. Apa yang terjadi ?
Analisis hasil yang diperoleh !
j.
Set nilai variabel atribut untuk day, month, dan year yang benar menggunakan method
setDate milik kelas DateThree !
k.
l.
m. Kompilasi dan jalankan program tersebut. Apa yang terjadi ? Analisis hasil tersebut !
n.
4.
248
Set nilai variabel atribut day, month, year yang salah. Kompilasi dan jalankan program
tersebut ! Apa yang terjadi ? Analisis hasil tersebut !
Pada Praktikum ini Anda diminta membuat kelas dan konstruktornya. Ikuti langkah berikut ini.
a.
b.
c.
Tambahkan konstruktor lain yang menerima, memverifikasi, dan mengisi variable month,
day, year.
d.
e.
Buat kelas DateFourTest untuk membuat obyek DateFour d1 dan d2, dimana d1 dibuat
menggunakan konstruktor tanpa argumen dan d2 dibuat menggunakan konstruktur dengan
argumen.
f.
Di dalam kelas DateFour, panggil method display untuk menampilkan nilai day, month,
dan year untuk d1 dan d2.
g.
Kompilasi dan jalankan program. Apa yang terjadi ? Analisis hasil yang diperoleh !
5.
Pada Praktikum ini Anda diminta untuk menggunakan konstruktor suatu kelas untuk
menginisialisasi obyek. Ikuti langkah berikut ini.
a.
b.
Konstruktor tanpa argumen yang mencetak pesan "Default persegi panjang dibuat dengan
panjang=5, lebar=5" dan set variable panjang ke 25 dan variabel lebar ke 10.
Konstruktor yang mengambil 2 argumen integer w dan h. Set variabel panjang ke w dan
lebar ke h jika dan hanya jika nilai w dan h lebih besar dari 0 dan lebih kecil dari 30. Pesan
error harus dimunculkan jika w dan h di luar interval tersebut.
c.
d.
249
250
LAMPIRAN D
PRAKTIKUM - 4
Praktikum 4.1
+
+
+
+
+
Vehicle
load : double
maxLoad : double
Vehicle(max_Load: double)
getLoad() : double
getMaxLoad() : double
Weight in kilograms
Weight in kilograms
Pada kelas Vehicle yang dideklarasikan di atas, semua atributnya memiliki mode akses public.
Oleh karenanya, program TestVehicle1 dapat mengakses atribut tersebut secara langsung.
a.
b.
Sertakan dua buah atribut publik, yaitu load: berat kendaraan pada saat sekarang dan
maxLoad: batas maksimum beban kendaraan.
Sertakan sebuah konstruktor publik untuk menset nilai atribut maxLoad.
Sertakan dua buah method bersifat publik: getLoad, untuk mengembalikan nilai atribut
load dan getMaxLoad, untuk mengembalikan nilai atribut maxLoad
Bacalah kode program dalam TestVehicle.java. Program tersebut akan mengalami masalah ketika
kotak yang terakhir ditambahkan ke dalam kendaraan, karena kode program tidak mengecek
apakah penambahan kotak tersebut melebihi batas maksimumnya (maxLoad) atau tidak.
d.
Praktikum 4.2
Untuk menyelesaikan masalah pada Praktikum 4.1 di atas, data atribut load dan maxLoad
disembunyikan dan untuk mengaksesnya disediakan method addBox, yang akan melakukan proses
pengecekan apakah beban kendaraan tersebut berlebih atau tidak.
+
+
+
+
Vehicle
load : double
maxLoad : double
Vehicle(max_Load: double)
getLoad() : double
getMaxLoad() : double
addBox(weight: double) : boolean
Weight in kilograms
Weight in kilograms
a.
b.
Salin kode program dari Praktikum 4.1, ubahlah kelas Vehicle tersebut sesuai dengan diagram
UML di atas.
c.
Bacalah kode program dalam TestVehicle.java. Program tersebut tidak dapat memodifikasi atribut
load secara langsung, tetapi harus melalui method addBox. Method ini akan mengembalikan nilai
true atau false dan akan ditampilkan di layar.
d.
e.
251
Praktikum 4.3
Pada Praktikum kali ini, Anda diminta untuk membuat kelas Account sederhana. Simpan file nya
ditempatkan ditempatkan di package Banking. Buatlah sebuah program untuk menguji kelas ini
bernama TestBankin yang dalamnya membuat sebuah account. Kelas ini juga menginisialisasi nilai
dari account tersebut dan melakukan beberapa transaksi sederhana, untuk kemudian mencetak nilai
akhir dari account tersebut.
Banking
+
+
+
+
Account
balan ce : double
Accou nt(init_balance : double)
getBa lance() : double
depos it(amt : double) : boolean
withd raw(amt : double) : boolean
a.
b.
Buat sebuah kelas Account di dalam file Account.java di dalam direktori banking. Kelas ini
harus mengimplementasikan model diagram UML di atas.
Deklarasikan sebuah atribut obyek yang bersifat private: balance. Atribut ini berisikan
nilai balance dari account bank yang bersangkutan !
Deklarasikan sebuah konstruktor public yang menggunakan satu parameter
(init_balance) yang mempopulasikan atribut balance !
Deklarasikan sebuah method publik getBalance yang mengambil nilai current balance !
Deklarasikan sebuah method publik deposit yang menambahkan nilai parameter amount ke
dalam current balance !
Deklarasikan sebuah method publik withdraw yang mengambil parameter amount dari nilai
current balance
kompilasi TestBanking.java. Proses kompilasi ini juga akan mengkompilasi semua kelas yang
digunakan dalam program, sehingga file Account.java akan terkompilasi juga di bawah direktori
banking. javac d . TestBanking.java
c.
d.
Praktikum 4.4
Banking
+
+
+
+
+
Customer
firstName : String
lastName : String
account : Account
Customer(f : String, l : String)
getFirstName() : Str ing
getLastName() : Stri ng
getAccount() : Accou nt
setAccount(acct : Ac count)
has
1+
+
+
+
Account
balan ce : double
Accou nt(init_balance : double)
getBa lance() : double
depos it(amt : double)
withd raw(amt : double)
a.
b.
Salin file project Banking dari tugas sebelumnya ke dalam direktori ini !
c.
Buatlah kelas Customer di dalam file Customer.java di dalam direktori banking. Direktori ini
merepresentasikan struktur package program yang kita buat dalam bahasa Java. Kelas ini haruslah
mengimplementasikan model diagram UML seperti di atas.
252
d.
Deklarasikan dua accessor yang bersifat public untuk atribut obyek tersebut, method
getFirstName dan getLastName yang mengembalikan atribut yang bersangkutan !
Deklarasikan method setAccount untuk mengeset atribut account !
Deklarasikan method getAccount untuk mengambil atribut account !
Di dalam direktori utama, kompilasi dan jalankan program TestBanking. Apa yang akan terjadi ?
Praktikum 4.5
1.
Buatlah sebuah aplikasi yang dinamakan dengan TestArray. Dalam method main(),
deklarasikan dua buah variabel yaitu array1 dan array2. Kedua variabel tersebut haruslah
bertipe int[] (array dari integer) !
2.
Dengan menggunakan notasi kurung kurawal ({}), inisialisasikan array1 dengan nilai delapan
bilangan prima pertama: 2,3,5,7,11,13,17 dan 19 !
3.
Tampilkan isi dari array1. Untuk hal tersebut dapat digunakan method printArray untuk
menunjukkan nilainya. Kompilasikan program dan jalankan !
4.
Berikan nilai variabel array2 yang nilainya sama dengan array1. Modifikasi elemen yang
berindeks genap di dalam array2 hingga nilainya sama dengan indeksnya (misal, array2[0] =
0, dan array2[2] = 2, dan seterusnya). Kompilasikan program TestArray tersebut dan
jalankan. Perubahan apa yang terjadi pada array tersebut ?
253
254
LAMPIRAN E
PRAKTIKUM - 5
Praktikum 5.1
a.
Deklarasikan sebuah variabel yang dinamakan matrix dengan tipe int[][] (array dari array
int). Inisialisasikan matriks array tersebut dengan sebuah array dari lima array !
b.
Populasikan setiap array yang di dalam (inner array) dengan cara sebagai berikut: lakukan loop
dalam matrix dari nol hingga panjang array tersebut, gunakan i sebagai index. Di setiap iterasi,
berikan nilai pada matrix[i] dengan sebuah array integer baru yang berukuran i. Lalu, lakukan
proses loop pada setiap elemen dari array tersebut, dengan menggunakan variabel index j. Di
setiap kali iterasi, berikan nilai matrix[i][j] dengan nilai (i * j) !
c.
Cetak array matrix dengan melakukan iterasi pada array bagian luar (outer array) dan cetak
setiap inner array pada baris yang terpisah. Kompilasikan program TestArrays dan jalankan.
Apa yang akan terjadi ?
Praktikum 5.2
Banking
+
+
+
+
Bank
custo mers : Custom er []
numbe rOfCustomers : int
Bank( )
addCu stomer(f: Str ing, l: String )
getNu mOfCustomers( ) : int
getCu stomer(index: int) : Custom er
serves
0..*
Customer
has
Account
1.
Buatlah sebuah direktori banking. Salin file yang ada di direktori Banking dari tugas
sebelumnya ke dalam direktori banking tersebut. Modifikasi kelas Account !
2.
Ubahlah method deposit sehingga method ini mengembalikan nilai true (yang berarti bahwa
proses deposit berhasil).
3.
Ubahalah method withdraw untuk menguji bahwa jumlah uang (amout/amt) yang ditarik tidak
lebih besar dari jumlah uang di balance. Jika amt lebih kecil dari balance, maka kurangi sejumlah
amount dari balance dan kembalikan nilai true. Jika tidak, maka balance dibiarkan dan kembalikan
nilai false !
4.
Tambahkan dua atribut pada kelas Bank: customers (array dari obyek Customer) dan
numberOfCustomers (nilai integer yang menyatakan jumlah pelanggan) !
5.
Tambahkan sebuah konstruktor public yang menginisialisasi array customers dengan satu
ukuran maksimum tertentu (paling tidak lebih besar dari lima) !
6.
Tambahkan sebuah method addCustomer. Method ini akan membuat sebuah obyek Customer
dari dua parameter (first name dan last name) dan meletakkannya dalam array customer. Method
ini juga harus menambahkan nilai (increment) atribut numberOfCustomers !
7.
8.
Tambahkan method getCustomer. Method ini akan mengembalikan obyek Customer yang
diasosiasikan dengan parameter index yang diberikan. Kompilasikan program TestBanking
tersebut dan jalankan. Apa yang akan terjadi?
255
Praktikum 5.3
Banking
#
+
+
+
+
Account
balan ce : double
Accou nt(init_bala nce : double)
getBa lance() : do uble
depos it(amt : dou ble) : boolea n
withd raw(amt : do uble) : boole an
Saving sAccount
- inte restRate : d ouble
+ Savi ngsAccount(b alance : dou ble,
inter est_rate: do uble)
Checkin gAccount
- overdraftProtecti on : double
+ CheckingAccount(b alance : doub le)
+ CheckingAccount(b alance : doub le,
protect: doub le)
+ withdraw(amt : do uble) : boole an
Mulailah dengan masuk ke direktori kerja anda. Pada package Banking, tambahkan subclass
SavingsAccount dan CheckingAccount, seperti tergambar di atas !
a.
Buatlah sebuah direktori banking. Salinlah file proyek Banking dari proyek sebelumnya ke
dalam direktori ini !
b.
Pada diagram UML, kelas Account telah berubah. Atribut balance sekarang memiliki mode
akses protected (diitunjukkan dengan karakter #)
c.
d.
e.
f.
Tambahkan sebuah konstruktor publik yang menggunakan dua parameter: balance dan
protect. Konstruktor ini haruslah melewatkan parameter balance pada konstruktor induk
dengan
memanggil
super(balance)
dan
memberikan
nilai
pada
atribut
overdraftProtection.
g.
Tambahkan pula sebuah konstruktor publik yang menggunakan sebuah parameter: balance.
Konstruktor ini haruslah melewatkan parameter balance pada konstruktor yang lain (overloaded
constructor) dengan pemanggilan this.
h.
Kelas CheckingAccount harus meng-override method withdraw. Kelas ini juga harus
melakukan pengecekan berikut: jika current balance mencukupi untuk proses penarikan
(withdraw), maka lakukan proses penarikan biasa. Jika tidak dan jika ada overdraft protection,
maka lakukan proses untuk menutupi selisih tersebut (balance - amount) dengan nilai
overdraftProtection. Jika jumlah yang dibutuhkan untuk menutupi overdraft lebih besar
dari level proteksi yang ada sekarang, maka batalkan seluruh proses transaksi tersebut.
i.
Dalam direktori kerja, kompilasi dan jalankan program TestBanking. Apa yang akan terjadi ?
Praktikum 5.4
Banking
Bank
serves
0..* Customer
has
0..*
SavingsAccount
Account
CheckingAccount
a.
Buatlah sebuah direktori banking. Salin file Banking dari tugas sebelumnya ke dalam direktori
banking tersebut.
b.
Modifikasikan kelas Customer sehingga kelas ini mampu memiliki banyak account. Kelas ini
haruslah memiliki method public berikut: addAccount(Account),getAccount(int),dan
getNumOfAccounts().
256
Gunakan operator instanceof untuk menguji account jenis apa yang dimiliki dan set
account_type ke dalam nilai yang sesuai, seperti Savings Account atau Checking Account !
d.
Cetak jenis dari account dan balance nya. Gunakan pembuat format currency_format untuk
membuat format mata uang yang sesuai !
e.
Praktikum 5.5
Buatlah sebuah direktori banking. Salin file Banking dari tugas sebelumnya ke dalam direktori
banking/domain.
Dalam tahap ini, proyek Banking yang dibuat membutuhkan hirarki package yang lebih kompleks
karena anda akan membuat sebuah kelas CustomerReport yang terdapat di dalam package
banking.reports.
Banking
Reports
CustomerReport
Domain
Customer
<<uses>>
Bank
- bank Instance : Bank
- Bank ()
+ getB ank() : Ban k
Modifikasikan kelas Bank dengan menambahkan method yang bertipe public dan static,
getBank, yang mengembalikan instance dari kelas Bank.
b.
Instance tunggal ini haruslah memiliki modifier static dan private. Buat pula konstruktor
Bank menjadi private.
Cari baris kode yang ditandai dengan blok comment sebagai berikut: /*** ***/. Ubah baris ini
menjadi pengembalian berupa obyek bank Singleton.
d.
257
258
LAMPIRAN F
PRAKTIKUM - 6
Praktikum 6.1
#
#
+
+
Animal
legs: int
Animal(legs : int)
walk()
eat()
+
+
+
+
+
+
Cat(name : String)
Cat()
getName(): String
setName(name: String)
play()
eat()
a.
b.
c.
d.
e.
f.
+ getName(): String
+ setName(name: String)
+ play()
Cat
Spider
+ Spider()
+ eat()
<<interface>>
Pet
Fish
+
+
+
+
+
+
Fish()
getName(): String
setName(name: String)
play()
walk()
eat()
Buat kelas Animal, yang merupakan superclass bertipe abstrak dari semua jenis binatang !
Buatlah sebuah kelas Spider !
Buatlah sebuah interface Pet seperti dalam diagram UML !
Buat sebuah kelas Cat yang meng-extend kelas Animal dan mengimplementasi interface Pet !
Buat sebuah kelas Fish yang meng-extend kelas Animal. Override method dalam kelas Animal
untuk menunjukkan ikan (fish) tidak dapat berjalan dan tidak memiliki kaki !
Buatlah sebuah program TestAnimals. Dalam method main, buat dan lakukan manipulasi
terhadap kelas-kelas yang telah dibuat sebelumnya !
Contoh:
Fish d = new Fish();
Cat c = new Cat(Fluffy);
Animal a = new Animal();
Animal e = new Spider();
Pet p = new Cat();
Mulai dengan memanggil method di dalam masing-masing obyek, lalu lakukan proses casting terhadap
obyek, lalu menggunakan konsep polimorfisme, dan gunakan super untuk memanggil method pada
superclass.
Praktikum 6.2
Masuklah ke dalam direktori kerja. Buatlah sebuah direktori Banking. Salin file proyek Banking dari
tugas sebelumnya ke dalam direktori ini.
#
+
+
+
+
Account
balance : double
Account(init : double)
getBalance() : double
deposit(amt : double)
withdraw(amt : double)
CheckingAccount
- overdraftProtection : double
+ CheckingAccount(balance : double)
+ CheckingAccount(balance : double,
protect: double)
+ withdraw(amt : double)
<<exception>>
Exception
<<exception>>
OverdraftException
- deficit : double
+ OverdraftException(message : String
deficit: double)
+ getDeficit(): double
259
b.
Tambahkan sebuah atribut private yang bernama deficit dengan tipe double. tambahkan
pula method pengakses public yang bernama getDeficit !
c.
Tambahkan sebuah konstruktor public yang menggunakan dua argumen: message dan
deficit. Parameter message dilewatkan pada konstruktor superclass sementara parameter
deficit menginisialisasi atribut deficit !
Tulis kembali method withdraw sehingga method ini tidak mengembalikan satu nilai (void).
Deklarasikan pula kalau mehtod ini melemparkan eksepsi OverdraftException !
e.
Ubah kode tersebut sehingga ia melemparkan sebuah eksepsi baru yang menyatakan insufficient
fund dan nilai defisitnya (jumlah yang diminta dikurangi dengan current balance) !
Tulis kembali method withdraw sehingga method ini tidak mengembalikan satu nilai (void).
Deklarasikan pula kalau mehtod ini melemparkan eksepsi OverdraftException !
g.
Ubah kode dalam kelas ini sehingga ia melemparkan sebuah eksepsi jika diperlukan. Ada dua hal
yang perlu ditangani. Pertama, kasus defisit tanpa overdraft protection (perlindungan ketika terjadi
penarikan uang berlebihan); untuk kasus ini, gunakan pesan no overdraft protection untuk
eksepsi kategori ini. Yang kedua, jumlah overdraftProtection mencukupi untuk menutupi
nilai defisit; dalam kasus ini gunakan pesan insufficient fund for overdraft protection untuk
eksepsi ini !
h.
Praktikum 6.3
a.
b.
Deklarasikan sebuah variabel yang berisi sebuah obyek File yang diinisialisasikan dari nama file
yang berasal dari argumen command-line.
c.
Di dalam blok try-catch, buat sebuah buffered input stream reader berdasarkan pada stream
System.in (input standar) !
d.
e.
Tuliskan sebuah loop while yang akan membaca setiap baris dari stream input console dan
mencetak baris tersebut ke file. Setiap baris haruslah didahului oleh nomor baris !
f.
260
Praktikum 6.4
Masuklah ke dalam direktori kerja. Salinlah file Banking dari tugas sebelumnya.
Banking
Bank
serves
Customer
0..*
has
0..* Account
SavingsAccount
CheckingAccount
Ubah deklarasi pada atribut customers menjadi tipe List dan hilangkan atribut
numberOfCustomers !
Ubah konstruktor Bank sehingga ia menginisialisasi atribut customers menjadi sebuah obyek
ArrayList yang baru !
Ubah method addCustomer untuk menggunakan method add dari kelas ArrayList !
Ubah method getCustomer untuk menggunakan method get dari kelas ArrayList !
Ubah method getNumOfCustomers untuk menggunakan method size dari kelas
ArrayList!
Praktikum 6.5
Buatlah sebuah kelas yang dinamakan ChatClient yang mengimplementasikan disain GUI seperti di
bawah ini:
Terdapat empat komponen di dalam GUI ini. Komponen utamanya adalah TextArea. Komponen yang
terletak di bawah adalah TextField. Ada dua buah komponen Button di sebelah kanan.
1.
Buat sebuah kelas ChatClient dengan empat atribut private, satu untuk masing-masing
komponen. Di dalam konstruktor, inisialisasikan masing-masing atribut komponen tersebut. Text
area haruslah memiliki tinggi 10 baris dan lebar 50 kolom, text field memiliki lebar 50 kolom, dan
tombol kirim memiliki kata Send pada tampilannya, dan begitu juga pada tombol keluar !
2.
Buat sebuah method launchFrame yang akan membuat layout dari komponen ! Anda diberi
kebebasan untuk menggunakan layout manager apapun !
3.
Buat sebuah method main. Dalam method ini, instantiasikan sebuah obyek ChatClient, lalu
panggillah method launchFrame !
261
Praktikum 6.6
Buatlah sebuah kelas yang dinamakan CalculatorGUI yang mengimplementasikan disain GUI
seperti di bawah ini :
Terdapat text field pada bagian atas frame (diguanakan untuk menampilkan hasil perhitungan) dan
sebuah kumpulan tombol yang berukuran 4 x 4 (16 buah). sebuah label juga dapat digunakan untuk
menampilkan hasil perhitungan.
262
LAMPIRAN G
PRAKTIKUM - 7
Praktikum 7.1
Salinlah file kelas CalculatorGUI dari tugas sebelumnya ke dalam direktori kerja anda !
Tugas anda adalah untuk mengimplementasikan ActionListener pada setiap tombol di dalam GUI.
Untuk memudahkan tugas anda, anda dapat menyalin kelas Calculator dari tugas sebelumnya.
Anda dapat menggunakan instance dari kelas ini sebagai model dari perilaku kalkulator. Perilaku dari
method ini cukup sederhana. Ada sebuah method untuk setiap operasi (opAdd, opSubtract,
opMultiply, dan opDivide) dan tanda sama dengan (opEquals). Masing-masing method ini
mengambil satu angka (tipe String) dan mengembalikan hasilnya (dalam tipe String). Contoh:
(3.25 * 2 + 5 = 11.5)
Calculator calc = new Calculator();
String result;
result = calc.opMultiply(3.25); // result is 3.25
result = calc.opAdd(2); // result is 6.5
result = calc.opMultiply(5); // result is 11.5
Gunakan sebuah model yang memungkinkan anda untuk memisahkan logika aplikasi dari presentasi
dan kontrol pada aplikasi. Ini merupakan contoh sederhana dari pola disain Model-View-Controller.
Dalam kasus ini, kelas Calculator mengimplementasikan model dan kelas CalculatorGUI
mengimplementasikan baik view (tombol, frame, dan layout) maupun controller nya (event handler) !
Praktikum 7.2
Salinlah file kelas ChatClient dari tugas sebelumnya ke dalam direktori kerja anda.
a.
b.
c.
Buat sebuah kotak pilihan (choice box) yang berada di bawah tombol kirim dan keluar. Masukkan
sejumlah pilihan sehingga memungkinkan pengguna untuk memilih nama user yang akan
digunakan dalam chatting. Ubah ActionListener dari tombol kirim, sehingga user name ikut
disertakan ke dalam pesan sebelum ditampilkan ke output text area !
Buat sebuah menubar. Tambahkan menu File dan Help ! Lalu Tambahkan sebuah item menu quit
pada menu File. Ketika menu tersebut dipilih, program akan berhenti !
Cobalah untuk bereksperimen dengan variasi warna dan huruf pada komponen !
Praktikum 7.3
Tujuan dari praktikum kali ini adalah untuk membuat tiga thread dan menjalankannya pada saat yang
bersamaan. Ketika ketiga thread tersebut berjalan, mereka akan mencetak namanya pada area teks.
Dengan melihat apa yang tercetak pada area teks, Anda dapat mempelajari bagaimana thread bekerja.
a.
b.
c.
d.
263
Praktikum 7.4
Salinlah file kelas ChatClient dari tugas sebelumnya ke dalam direktori kerja anda.
1.
2.
3.
4.
5.
6.
264
Di dalam method launchFrame, anda membutuhkan koneksi ke server (buatlah koneksi socket) !
Anda membutuhkan stream (input dan output) dari koneksi socket sehingga anda dapat
mengirimkan pesan ke server, dan menerima pesan lain dari server !
Anda membutuhkan RemoteReader sebuah runnable object yang dapat dijalankan oleh
sebuah thread dan secara terus menerus mendengarkan masukan pada input stream yang didapat
dari socket !
Anda perlu memodifikasi method actionPerformed sehingga ketika user mengklik tombol
send, anda mengirimkan teks ke server (dengan menggunakan output stream), bukan meletakkan
teks ke dalam text area !
Anda perlu memodifikasi action listener pada input text field untuk melakukan hal serupa di atas
(mengirimkan pesan ke server) !
Anda membutuhkan obyek RemoteReader meletakkan pesan yang datang ke dalam text area !
LAMPIRAN H
UJI COBA UJIAN SERTIFIKASI INTERNASIONAL
1.
2. After execution of the code fragment below, what are the value of the variables x1, y1, and z1?
int x=10; int y =10; int z=10; int x1, y1, z1;
x1=++y;
y1=z++;
z1=z;
A. x1 = 10 , y1 = 10 and z1=10
4. Consider the following application. Assume that MyList class is declared in MyList.java and ListManager class is declared in
ListManager.java file.
public class MyList{
int size=1;
public static void main(String [] args){
MyList list=new MyList();
list.size=10;
ListManager lm=new ListManager();
lm.expandList(list);
System.out.println("list.size="+list.size);
}
} //end of MyList
public class ListManager{
public void expandList(MyList l){
l.size=l.size+10;
}
}//end of ListManager
What will be output of the above program?
A. list.size=0
B. list.size=10
C. list.size=11
D. list.size=20
265
266
267
16. For the following code, please consider that super class is defined in question #15:
public class MyTest extends Test{
private void demo() throws IndexOutOfBoundsException,
ClassNotFoundException{
//something here
}
}//end of MyTest class
What will happen if you try to compile above class?
A. It will compile successfully.
B. Compiler error: Exception java.lang.ClassNotFoundException in throws clause of void MyTest.demo() is not compatible with
void Test.demo().
C. Compiler error: Cannot reduce visibility of the inherited method from Test.
D. Both B and C
17. Consider the following code:
public class Test{
public void demo(String [] list){
try{
String s=list[list.length+1];
System.out.println(s);
}catch(ArrayIndexOutOfBoundException e){
return;
}finally{
System.out.println("Finally here.");
}
}
public static void main(String [] args){
Test t=new Test();
String [] list={"one","two"};
t.demo(list);
System.out.println("Done!");
}
}//end of Test class
268
C. Tested z.
269
C. i = 1 j = 2
C. i = 0 j = 3
D. i = 1 j = 3
C. i = 0 j = 3
}
System.out.println("i = "+i+" j = "+j);
}
Which lines would be part of the output?
A. i = 0 j = 0
B. i = 1 j = 1
C. i = 0 j = 3
270
String s="Hi";
StringBuffer sb=new StringBuffer(s);
String s1=new String("There");
StringBuffer sb1=new StringBuffer(s1);
if(s==sb){
System.out.println("s==sb");
}
if(s.equals(sb)){
System.out.println("s.equals(sb)");
}
if(s1.equals(sb1)){
System.out.println("s1.equals(sb1)");
}
271
String s=null;
String t="null";
if (s==t) {
System.out.println("s equal to t");
}else{
System.out.println("s not equal to t");
}
what will result if you try to compile and run above code?
A. it compiles successfully, but throws NullpointerException at if (s==t)
C. It compiles successfully and output "s equal to t"
272
What will be result if you try to compile and run above code?
A. Compile error produced, "variable s may not have been initialized."
B. It compile successfully, but throws NullpointerException at if ( s.equals(null) )
C. It compile successfully, and outputs "s is null."
D. It compile successfully, and outputs "s is not null."
36. Consider the following code:
public class MyList{
private static final int MAX_SIZE = 10;
private Object [] list = new Object[MAX_SIZE];
public void add(Object obj){
int size=list.length;
if(size >= MAX_SIZE){
class ListExpander{
public void expand(){
Object temp [] = list;
list = new Object[size+MAX_SIZE];
for ( i=0;i<temp.length; i++){
list[i]=temp[i];
}
}//end of public void expand()
} end of class ListExpander
ListExpander listEx = new ListExpander();
listExp.expand();
list[size] = obj;
}//end of if
}//end of add
}//end of class MyList
What will be result if you try to compile and run the above code:
A. Compiler error reported, "Cannot refer inside an inner class to a non-final variable size' defined in a different method."
B. Compiler error reported, "Cannot refer inside an inner class to a private member variable 'list' defined in enclosing class
MyList."
C. Compiler error reported, "Cannot refer inside an inner class to a static member variable MAX_SIZE defined in enclosing class
MyList."
D. It compiles and runs successfully.
37. Consider following example of an inner class
public class MyTest{
public String publicVariable = "a";
private String privateVariable = "b";
public static int SIZE = 0;
private static int MAX_SIZE = 0;
public static class DemoHelper{
public void demo{
System.out.println("Demo = "+XXX);
}
}//end of inner class
}
which variable of the MyTest class will be able to use in place of XXX?
A. publicVariable
B. privateVariable
C. SIZE
D. MAX_SIZE
273
38. What will be result if you try to compile and run following code?
public class Record extends String{}
A. Compiler error reported, "Can not extend a final class."
B. Compiler error reported, "Must implement method int compareTo(Object)."
C. Compile and run successfully.
D. None of the above.
39. Consider the following two classes:
public class Parent{
protected void demo() throws Exception{}
} // end of Parent class
public class Child extends Parent{
private void demo() {}
}
What will be result if you try to compile above two classes?
A. Compiler object for the method of a Child class, "Can not reduce the visibility of the inherited method."
B. Compiler object for demo() method of a Child class, "Inherited method is not compatible with void Parent.demo() throws
Exception."
C. Compile successfully.
D. None of the above
40. Consider the following two classes:
public class Parent{
protected void demo() {}
} // end of Parent class
274
275
47. What will be result if you try to compile the following code?
public class Parent{
String name=null;
public Parent(String n){
name=n;
}
}
public class Child extends Parent{
String type="X";
}
A. Compile successfully.
B Compiler error reported, because Parent class did not declare constructor with arguments ().
C. Compiler error reported, because Child class did not declare a constructor.
D. Both of the above B and C
48. What will be legal statement in the following method?
public void demo(int x){
XXX y=10;
}
A.public int
B. int
C. final int
D. static int
49. What will be result if you try to compile and run following code fragement?
public void demo (String [] args){
int i=1;
for(int i=0;i<args.length;i++){
System.out.println(args[i]);
}
}
A. Compile successfully, but throws IndexOutOfBoundException during runtime.
B. Compile error reported, "Local name i is already defined."
C. Throws NullPointerException during runtime
D. None of the above
50. Given:
1
2
3
4
5
6
7
8
9
Which of the following constructor signatures MUST exist in the Demo class for Derived to compile correctly?
(1) public Demo(int a, int b)
(2) public Demo(int c)
(3) public Demo()
52. Which of the following class declarations for a normal top level class are incorrect?
(1) public synchronized class Base extends Thread
(2) private protected class Base
(3) public abstract class Base
(4) class Base extends Thread
53. The GenericFruit class declares the following method:
public void setCalorieContent(float f)
You are writing a class Apple to extend GenericFruit and wish to add methods which overload the method in GenericFruit. Select
all of the following which would constitute legal declarations of overloading methods.
(1) protected float setCalorieContent(String s)
(2) protected void setCalorieContent(float x)
(3) public void setCalorieContent(double d)
(4) public void setCalorieContent(String s) throws NumberFormatException
276
Which of the following descriptions of the results of various inputs to the method are correct?
(1) Input = "0.1234". Result: factor = 0.1234, "Finally" is printed, true is returned
(2) Input = "0.1234". Result: factor = 0.1234, "Finally" is printed, false is returned
(3) Input = null. Result: factor = NaN, "Finally" is printed, false is returned
(4) Input = null. Result: factor unchanged, "Finally" is printed, NullPointerException is thrown
56. Given the following code fragment:
XXXX x; // variable x is declared and initialized here
switch(x) {
case 100:
System.out.println("One Hundred");
break;
case 200:
System.out.println("Two Hundred");
break;
case 300:
System.out.println("Three Hundred");
break;
}
Choose all of the declarations of x which will not cause a compilation error.
(1) byte x = 100;
(2) short x = 200;
(3) int x = 300;
57. In the following code for a class in which methodA has an inner class.
1
2
3
4
5
6
7
8
9
10
11
12
13
Which variables would the statement in line 8 be able to use in place of XX? Check all that apply.
(1) int ID (line 2)
(2) String name (line 3)
(3) int nn (line 4)
277
58. What happens when we attempt to compile and run the following code?
1
2
3
4
5
6
7
(1) The program will compile and run, producing the output "N = -1"
2) The program will compile and run, producing the output "N = 1"
(3) A run time ArithmeticException will be thrown
(4) The program will compile and run, producing the output "N = 0"
59.
What will happen when you attempt to compile and run the following code? (Assume that the code is compiled and run
with assertions enabled.)
public class AssertTest{
public void methodA(int i){
assert i >= 0 : methodB();
System.out.println(i);
}
public void methodB(){
System.out.println("The value must not be negative");
}
public static void main(String args[]){
AssertTest test = new AssertTest();
test.methodA(-10);
}
}
278
61. What will happen when you attempt to compile and run the following code?
class MyParent{
int x, y;
MyParent(int x, int y){
this.x = x;
this.y = y;
}
public int addMe(int x, int y){
return this.x + x + y + this.y;
}
public int addMe(MyParent myPar){
return addMe(myPar.x, myPar.y);
}
}
class MyChild extends MyParent{
int z;
MyChild (int x, int y, int z){
super(x,y);
this.z = z;
}
public int addMe(int x, int y, int z){
return this.x + x + this.y + y + this.z + z;
}
public int addMe(MyChild myChi){
return addMe(myChi.x, myChi.y, myChi.z);
}
public int addMe(int x, int y){
return this.x + x + this.y + y;
}
}
public class MySomeOne{
public static void main(String args[]){
MyChild myChi = new MyChild(10, 20, 30);
MyParent myPar = new MyParent(10, 20);
int x = myChi.addMe(10, 20, 30);
int y = myChi.addMe(myChi);
int z = myPar.addMe(myPar);
System.out.println(x + y + z);
}
}
(1) 300
(2) 240
(3) 120
(4) 180
(5) Compilation error
(6) None of the above
279
boolean a = true;
boolean b = false;
boolean c = true;
if (a == true)
if (b == true)
if (c == true)
System.out.println("Some things are true in this world");
else
System.out.println("Nothing is true in this world!");
else if (a && (b = c))
System.out.println("It's too confusing to tell what is true and what is false");
else
System.out.println("Hey this won't compile");
63 What will happen when you attempt to compile and run the following code?
interface MyInterface{}
public class MyInstanceTest implements MyInterface{
static String s;
public static void main(String args[]){
MyInstanceTest t = new MyInstanceTest();
if(t instanceof MyInterface){
System.out.println("I am true interface");
}else{
System.out.println("I am false interface");
}
if(s instanceof String){
System.out.println("I am true String");
}else{
System.out.println("I am false String");
}
}
}
(1) Compile-time error
(2) Runtime error
(3) Prints : "I am true interface" followed by " I am true String
(4) Prints : "I am false interface" followed by " I am false String"
(5) Prints : "I am true interface" followed by " I am false String"
(6) Prints : "I am false interface" followed by " I am true String"
64. What results from attempting to compile and run the following code?
public class Ternary{
public static void main(String args[]){
int a = 5;
System.out.println("Value is - " + ((a < 5) ? 9.9 : 9));
}
}
(1) prints: Value is 9
65. In the following pieces of code, A and D will compile without any error. True/False?
A:
B:
C:
D:
E:
(1) True
66. Which of the following collection classes from java.util package are Thread safe?
(1) Vector
(2) ArrayList
(3) HashMap
(4) Hashtable
280
67 What will happen when you attempt to compile and run the following code?
class MyThread extends Thread{
public void run(){
System.out.println("MyThread: run()");
}
public void start(){
System.out.println("MyThread: start()");
}
}
class MyRunnable implements Runnable{
public void run(){
System.out.println("MyRunnable: run()");
}
public void start(){
System.out.println("MyRunnable: start()");
}
}
public class MyTest{
public static void main(String args[]){
MyThread myThread = new MyThread();
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
myThread.start();
thread.start();
}
}
(1) Prints : MyThread: start() followed by MyRunnable:run()
(2) Prints : MyThread: run() followed by MyRunnable:start()
(3) Prints : MyThread: start() followed by MyRunnable:start()
(4) Prints : MyThread: run() followed by MyRunnable:run()
(5) Compile time error
(6) None of the above
68. What will be the result of executing the following code?
// Filename; SuperclassX.java
package packageX;
public class SuperclassX{
protected void superclassMethodX(){}
int superclassVarX;
}
// Filename SubclassY.java
1.
package packageX.packageY;
2.
3.
public class SubclassY extends SuperclassX
4.
{
5.
SuperclassX objX = new SubclassY();
6.
SubclassY objY = new SubclassY();
7.
void subclassMethodY()
8.
{
9.
objY.superclassMethodX();
10.
int i;
11.
i = objY.superclassVarX;
12.
}
13.
}
(1) Compilation error at line 5
(2) Compilation error at line 9
(3) Runtime exception at line 11
(4) None of these
69 What can cause a Thread to stop executing?
(1) Calling its own yield method
(2) Calling the yield method of another thread
(3) A call to the halt method of the Thread class
(4) Another thread is given higher priority
281
282
76. What will be the result of attempting to compile and run the following program?
public class TestClass{
public static void main(String args[ ] ){
A o1 = new C( );
B o2 = (B) o1;
System.out.println(o1.m1( ) );
System.out.println(o2.i );
}
}
class A { int i = 10; int m1( ) { return i; } }
class B extends A { int i = 20; int m1() { return i; } }
class C extends B { int i = 30; int m1() { return i; } }
(1) The progarm will fail to compile
(2) ClassCastException at runtime
(3) It will print 30, 20
(4) It will print 30, 30
(5) It will print 20, 20
77 Consider the following lines of code:
System.out.println(null + true); //1
System.out.println(true + null); //2
System.out.println(null + null); //3
Which of the following statements are correct? Select 1 correct option
(1) None of the 3 lines will compile
(2) All the 3 line will compile and print nulltrue, truenull and nullnull respectively
(3) Line 1 and 2 won't compile but line 3 will print nullnull
(4) Line 3 won't compile but line 1 and 2 will print nulltrue and truenull respectively
(5) None of the above
78 Which of the following are true about the "default" constructor? Select 2 correct options
(1) It is provided by the compiler only if the class does not define any constructor
(2) It initializes the instance members of the class
(3) It calls the default 'no-args' constructor of the super class
(4) It initializes instance as well as class fields of the class
(5) It is provided by the compiler if the class does not define a 'no- args' constructor
79. Which of these methods from the Collection interface return the value true if the collection object was actually modified by
the call? Select 3 correct options
(1) add( )
(2) retainAll( )
(3) containsAll( )
(4) contains( )
(5) remove()
80 Following is not a valid comment:
/* this comment /* // /** is not valid */
(1) True
(2) False
81 Which statements regarding the following code are correct?
class Outer{
private void Outer() { }
protected class Inner{}
}
Select 1 correct option
(1) This code won't compile
(2) Constructor for Outer is public
(3) Constructor for Outer is private
(4) Constructor for Inner is public
(5) Constructor for Inner is protected
283
(2) False
85. What happens when you try to compile and run the following class:
public class TestClass{
public static void main(String[] args) throws Exception{
int a = Integer.MIN_VALUE;
int b = -a;
System.out.println( a+ " "+b);
}
}
Select 1 correct option
(1) It throws an OverFlowException
(2) It will print two same -ive numbers
(3) It will print two different -ive numbers
(4) It will print one -ive and one +ive number of same magnitude
(5) It will print one -ive and one +ive number of different magnitude
86 Consider the following code snippet:
void m1() throws Exception{
try{
}catch (IOException e){
throw new SQLException();
}catch(SQLException e){
throw new InstantiationException();
}finally{
throw new CloneNotSupportedException() // this is not a
RuntimeException.
}
}
284
(2) System.out.println(iOther);
(4) System.out.println(iArgs);
285
94 Which of the following statements are true [Check all correct answers]
(1) Checked exceptions are derived directly from Exception
(2) Checked exceptions are derived directly from RuntimeException
(3) Unchecked exceptions are derived directly from Exception
(4) Unchecked exceptions are derived direclty from RuntimeException
(5) Exception and RuntimeException are both subclasses of Throwable
95 Which of the following keywords are valid when declaring a top level class? [Check all correct answers]
(1) private
(2) native
(3) final
(4) transient
(5) abstract
286
96 After the execution of the code-fragment below, what will be the values of a, b and c?
public class TechnoSample {
public static void main(String[] args) {
int a = 2, b = 3, c = 4;
a = b++ + c;
c += b;
b += a * 2;
System.out.println("a: " + a + " b: " + b + " c: " + c);
}
}
(1) a: 2 b: 18 c: 8
(2) a: 7 b: 12 c: 8
(3) a: 7 b: 18 c: 8
(4) a: 7 b: 18 c: 4
(5) None of the above
97 What, if anything, is wrong with the following code?
abstract class TestClass{
transient int j;
synchronized int k;
final void TestClass(){}
static void f(){
k = j++;
}
}
Select 2 correct options
(1) The class TestClass cannot be declared abstract
(3) The variable k cannot be declared synchronized
(5) The method f( ) cannot be declared static
(3) 4, 3, 4
(4) 4, 3, 3
287
What will be the output of compiling and running class B? Select 1 correct option
(1) It will print 10
(2) It will print 20
(4) It will throw an exception at Run time
(5) None of the above
101.
public class Test1{
public static void main(String[] args){
int arr[] = new int[3];
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
}
}
What will be the output?
A1. 0 0 0
A3. NullPointerException
A2. ArrayIndexoutOfBoundsException
A4. null null null
A2 Compiler
A3 Runtime
A4 Nothing
104.
public class Test4{
public static void method(){
System.out.println("Called");
}
public static void main(String[] args){
Test4 t4 = null;
t4.method();
}
}
What will be the output?
A1 "Called"
A2 Compiler
A3 Runtime Exception
105.
public class Test5{
public void Test5(){
System.out.println("Constructor1");
}
public Test5(){
System.out.println("Constructor2");
}
public static void main(String[] args){
Test5 t5 = new Test5();
}
}
What will be the output?
A1 "Constructor1"
A2 "Constructor2"
A3 "Constructor1""Constructor2"
A4 Compiler Errror
288
106.
public class Test6{
public Test6(){
this(4);
}
public Test6(byte var){
System.out.println(var);
}
public static void main(String[] args){
Test6 t6 = new Test6();
}
}
What will be the output?
A1 4
A2 4 4
107.
A3 Compiler Error
A3 Hai Hi
A4 Hi Hai
A4 Test8(){}
A4 int method(){}
A4 constructor
112 which of the following are valid combinations for class declaration?
A1 abstract final class Test12{}
A2 abstract static class Test12{}
A3 final static class Test12{}
A4 public final strictfp class Test12{}
113 which of the following are valid constructor signatures?
A1 public void className()
A2 public void className()
A3 private className()
A4 static className()
114. Which of the following modifiers can be used with top class declaration?
A1 static
A2 privatr
A3 public
A4 final
A5 abstract
289
A2 Static Instance
A3 Static
A2 Super class
A3 Sub class
A4 Compiler Error
290
A2 Compiler Error
A3 Runtime Exception
A4 None
A1 false true
A2 true false
A3 true true
A4 None of the above.
125
A1 true false
A2 false true
A3 true true
A4 Compiler error
291
292
LAMPIRAN I
JAWABAN SOAL UJI COBA UJIAN SERTIFIKASI INTERNASIONAL
1. D
26. C
51. 1,2
76. 1
101. A3
2. D
27. D
52. 1,3,4
77. 1,3
102. A2
3. A
28. C
53. 2,4
78. 1,2,5
103. A1
4. D
29. C
54. 1,4
79. 2
104. A2
5. B and D
30. A
55. 2,3
80. 5
105. A3
6. A and D
31. C
56. 1,2,3
81. 2
106. A3
7. C and D
32. A and B
57. 1
82. 1
107. A1, A3
8. A
33. B
58. 3
83. 1
108. A3, A4
9. B
34. D
59. 4
84. 2
109. A1
10. B
35. A
60. 1
85. 2,4
110. A2 A3
11. D
36. A
61. 4
86. 3
111. b
12. C and D
37. C and D
62. 5
87. 3
112. c, d
13. C and D
38. A
63. 4
88. 1,2,3
113. b, c
14. B, C, D and E
39. A
64. 2
89. 1,4
114. c, d, e
15. A
40. B
65. 1,4
90. 4
115. b, d
16. D
41. B
66. 1
91. 3
116. c
17. D
42. C
67. 4
92. 1
117. d
18. C
43. C
68. 4
93. 1,4,5
118. a
19. B
44. A
69. 1,2,3
94. 3,5
119. c
20. D
45. B
70. 3
95. 3
120. d
21. A, B, and C
46. A and B
71. 3
96. 3,5
121. A1, A4
22. C and D
47. B
72. 1,3
97. 3
122. A4
23. A and B
48. B and C
73. 5
98. 4
123. A3
24. D
49. B
74. 1,2
99. 3
124. A1
25. A and B
50. 2,3
75. 3
100. A1
125. A4
293
294
LAMPIRAN J
DAFTAR SERTIFIKASI INTERNASIONAL JAVA
295
296
DAFTAR PUSTAKA
th
1.
2.
3.
4.
Sun Academic Initiative, Fundamentals of Java Programming Language SL-110, Sun Microsystem
Press, 2005.
5.
Sun Academic Initiative, Java Programming Language SL-275, Sun Microsystem Press, 2005.
297
298
MEMAHAMI PEMROGRAMAN
BERORIENTASI OBYEK DENGAN JAVA
Pemrograman berorientasi obyek merupakan konsep pemrograman yang mengarahkan programmer ke
paradigma pembentukan obyek-obyek yang saling berinteraksi. Selain konsepnya lebih mudah dicerna oleh
pemrogram, baik yang awam sekalipun, konsep pemrograman berorientasi obyek mempermudah
pemeliharaan piranti lunak sehingga piranti lunak menjadi lebih fleksibel apabila akan direvisi atau
dikembangkan.
Teknologi Java merupakan salah satu teknologi yang saat ini berkembang pesat dalam waktu yang sangat
singkat. Penerimaan Java yang meluas ini mencerminkan kekuatan dan fitur teknis Java yang handal.
Karakteristik Java meliputi : platform yang netral, dinamis, Berorientasi obyek, penghapusan obyek secara
otomatis, keamanan yang tinggi, dan handal. Bahasa Pemrograman Java telah menjadi bahasa pemrograman
yang memiliki banyak kegunaannya. Java library mendukung pengembangan aplikasi dalam berbagai platform.
Teknologi Java menawarkan solusi dalam berbagai platform mulai dari platform untuk aplikasi desktop (Java
Standard Edition, J2SE), platform aplikasi enterprise (Java Enterprise Edition, J2EE), hingga aplikasi mobile
(Java Micro Edition, J2ME).
Para pengembang piranti lunak telah mengadopsi Java bukan sekedar untuk suatu pekerjaan pengembangan
aplikasi, tapi juga cukup menyenangkan dan praktis. Java menghilangkan sesuatu yang membosankan dan
meminimalisir kesalahan terus menerus pada pengembangan aplikasi. Java memberikan para pengembang
untuk memusatkan seluruh energinya pada rancangan dan funsionalitas program.
Prinsip Java adalah "Keep it simple! dan "Keep it learnable!". Dalam artian bahwa Java merupakan bahasa yang
mudah dipelajari karena kesederhanaannya. Oleh karena itu, saat ini telah banyak yang menggunakan Java
mulai dari kalangan pelajar, programmer, pengembang, dan praktisi IT dalam pembangunan perangkat
lunaknya.
Buku ini tidak membahas semua platform Java, namun hanya membahas Java Standard Edition saja. Buku ini
membahas utuh pemrograman Java Standard Edition mulai dari fundamental Java Programming Language,
Java Programming, dan Java Workshop untuk membangun aplikasi berbasis Java Standard Edition.
Selain membahas tentang pemrograman berorientasi obyek menggunakan Teknologi Java, buku ini juga
menyediakan soal-soal praktikum dan soal-soal ujian sertifikasi internasional sehingga diharapkan buku ini
dapat dijadikan rujukan yang dapat membantu pembacanya untuk menguasai pemrograman Java sekaligus
mengambil sertifikasi internasional Java.
299