Suatu program disebut "
benar" jika ia menyelesaikan suatu tugas sesuai dengan desainnya. Program disebut "
tangguh"
 jika ia bisa menangani suatu situasi yang tidak biasa dengan cara yang 
masuk akal. Misalnya, suatu program didesain untuk membaca angka yang 
diketik oleh user, kemudian menampilkan angka dengan urutan tertentu. 
Program tersebut benar jika ia bekerja untuk angka berapa pun. Program 
tersebut tangguh jika program tersebut bisa menangani input yang salah, 
misalnya jika user memasukkan sesuatu yang bukan angka, misalnya, dengan
 cara memberi tahu user bahwa input yang dia masukkan salah, dan 
mengabaikan input yang salah tersebut. Program yang tidak tangguh akan 
keluar tiba-tiba atau memberikan keluaran yang tidak bermakna dalam 
kondisi tertentu.
Semua program harusnya bekerja dengan benar. 
(Program yang dibuat untuk mengurutkan angka tetapi tidak mengurutkan 
dengan benar adalah program yang tidak berguna). Program tidak selalu 
harus tangguh secara total. Akan tetapi tergantung pada siapa yang akan 
menggunakan dan bagaimana program tersebut digunakan. Misalnya, program 
kecil yang digunakan hanya oleh Anda sendiri tidak harus tangguh total, 
karena kita tahu batas-batas dan bagaimana program tersebut bekerja.
Kebenaran
 suatu program sebenarnya lebih sulit dari apa yang kita bayangkan. 
Seorang programmer mencoba membuat program sesuai dengan spesifikasi 
tentang bagaimana sebuat program "seharusnya" bekerja. Hasil kerja 
programmer tersebut benar jika program yang ia buat bekerja sesuai 
dengan spesifikasinya. Tapi apakah itu berarti program tersebut benar? 
Bagaimana jika ternyata spesifikasinya kurang lengkap atau salah? 
Program yang benar seharusnya merupakan implementasi dari spesifikasi 
yang lengkap dan benar. Pertanyaannya apakah spesifikasi tersebut 
lengkap dan sesuai dengan yang diinginkan tercakup di luar domain ilmu 
komputer.
Banyak pengguna komputer memiliki pengalaman di mana
 program tidak bekerja atau crash. Dalam banyak hal, masalah tersebut 
hanya mengganggu saja, tapi kadang-kadang masalahnya lebih kompleks dari
 itu, misalnya hilangnya data atau uang. Jika komputer diberi tugas 
penting, konsekuensinya akan lebih serius apabila program tersebut 
berperilaku tidak normal.
Beberapa tahun yang lalu, kegagalan dua 
misi ruang angkasa ke Mars masuk dalam berita. Kedua kegagalan tersebut 
dipercaya karena masalah pada software, akan tetapi pada kedua kasus 
tersebut masalahnya bukan pada program yang tidak benar. Pada bulan 
September 1999, Orbiter Iklim Mars terbakar di atmosfer Mars karena data
 yang ditulis dalam satuan Inggris (inci, kaki, dll) dimasukkan ke dalam
 program komputer yang didesain untuk menerima input satuan Metrik 
(sentimeter, kilometer, dll). Beberapa bulan kemudian, Pendarat Kutub 
Mars jatuh karena softwarenya mematikan mesinnya terlalu cepat. Program 
yang dibuat seharusnya bisa mendeteksi tumpuan ketika pesawat mendarat 
dan baru kemudian mematikan mesin. Akan tetapi, roda pendarat 
kemungkinan macet yang menyebabkan program pemati mesin aktif sebelum 
pesawat menyentuh tanah. Sistem yang lebih tangguh akan mengecek 
terlebih dahulu ketinggian pesawat sebelum mesin dimatikan.
Masih 
banyak beberapa kisah tentang masalah yang disebabkan oleh jeleknya 
desain atau implementasi suatu software. Silakan lihat buku 
Computer Ethics
 karangan Tom Forester dan Perry Morrison untuk melihat beberapa insiden
 yang pernah terjadi. (Buku ini menceritakan tentang isu etika dalam 
bidang komputer. Buku ini mungkin penting sekali untuk dibaca oleh orang
 yang berkecimpung dalam dunia ilmu komputer).
Pada tahun 1985 dan
 1986, satu orang tewas dan beberapa lainnya terluka karena overdosis 
radiasi, pada saat melakukan perawatan radiasi dengan mesin radiasi yang
 komputernya tidak diprogram dengan benar. DI kasus lain, selama 10 
tahun hingga tahun 1992, sekitar 1000 pasien kanker menerima dosis 
radiasi sekitar 30% lebih rendah dari yang diberikan dokter karena 
kesalahan pemrograman.
Pada tahun 1985, sebuah komputer di Bank of
 New York menghancurkan data-data transaksi sekuritas yang sedang 
berjalan karena adanya kesalahan pada program. Butuh kurang dari 24 jam 
untuk memperbaiki program tersebut, akan tetapi pada saat itu, bank 
sudah kehilangan sekitar 5 juta US dollar karena bunga overnight yang 
harus dipinjam untuk mengkover masalah tersebut.
Pemrograman 
sistem kendali inersia dari pesawat tempur F-16 bisa membalik pesawat 
dari atas ke bawah ketika digunakan di atas khatulistiwa, untungnya 
masalah ini sudah ditemukan dalam simulasi. Pemindai luar angkasa 
Mariner 18 hilang karena kesalahan di satu baris program. Kapsul luar 
angkasa Gemini V salah mendarat beberapa ratus kilometer lebih jauh 
karena programmer lupa untuk memasukkan perputaran bumi ke dalam 
perhitungan.
Pada tahun 1990, layanan telephon jarak jauh AT&T
 terganggu di seluruh Amerika Serikat ketika program komputer yang baru 
dijalankan terbukti memiliki bug.
Contoh-contoh di atas adalah 
beberapa yang pernah terjadi. Masalah software adalah masalah yang 
sangat umum. Sebagai programmer, kita harus mengerti kenapa itu bisa 
terjadi dan bagaimana cara mengatasinya.
Salah satu bagian 
dari masalahnya dapat dilacak kepada bahasa pemrogramannya itu sendiri, 
begitu kata para penemu Java. Java didesain untuk memberikan proteksi 
terhadap beberapa jenis kesalahan. Bagaimana caranya suatu bahasa 
pemrograman menghindari kesalahan? Mari kita lihat beberapa contohnya.
Bahasa
 pemrograman terdahulu tidak membutuhkan variabel untuk dideklarasikan. 
Pada bahasa pemrograman tersebut, ketika suatu nama variabel digunakan 
dalam program, variabel akan otomatis dibuat. Mungkin ini terlihat lebih
 mudah dan nyaman daripada harus mendeklarasikan variabel beserta 
tipenya terlebih dahulu. Akan tetapi, ada konsekuensinya : Kesalahan 
ketik sedikit saja akan membuat komputer menciptakan variabel baru yang 
sebetulnya tidak kita inginkan. Kesalahan seperti ini pernah terjadi dan
 mengakibatkan hilangnya pesawat ruang angkasa.
Dalam bahasa 
pemrograman FORTRAN, perintah "DO 20 I = 1,5" adalah pernyataan pertama 
dari suatu perulangan. Sekarang, spasi tidak lagi suatu hal yang penting
 pada bahasa FORTRAN, sehingga perintah ini akan sama dengan 
"DO20I=1,5". Di lain pihak, perintah "DO20I=1.5" dengan tanda titik 
bukan koma, merupakan pernyataan pemberi nilai yang memberi nilai 1.5 ke
 dalam variabel DO20I. Misalnya ada kesalahan dalam mengetik koma 
menjadi titik, bisa jadi akan menyebabkan suatu roket meledak sebelum 
diluncurkan.
Karena FORTRAN tidak memerlukan variabel untuk 
dideklarasi, kompilernya akan senang menerima perintah "DO20I=1.5". Ia 
akan membuat variabel baru bernama DO20I. Jika FORTRAN membutuhkan 
variabel untuk dideklarasikan di awal, kompiler akan mengeluarkan pesan 
kesalahan di awal karena variabel DO20I tidak pernah dideklarasikan 
sebelumnya.
Hampir semua bahasa pemrograman saat ini perlu 
mendeklarasikan variabel sebelum digunakan, akan tetapi masih ada 
beberapa fitur pada bahasa pemrograman yang bisa menyebabkan kesalahan. 
Java sudah membuang fitur ini. Beberapa orang tidak suka karena ini 
membuat Java menjadi kurang feksibel dan kurang ampuh. Walaupun mungkin 
kritik ini benar, meningkatnya tingkat keamanan dan ketangguhan suatu 
program mungkin lebih dipentingkan dalam beberapa hal.
Pertahanan 
yang paling baik untuk mencegah beberapa macam jenis kesalahan adalah 
mendesain bahasa pemrograman di mana membuat kesalahan tidak mungkin 
sama sekali. Dalam kasus lain, di mana kesalahan tidak bisa dihilangkan 
sama sekali, bahasa pemrograman bisa didesain sehingga apabila kesalahan
 terjadi, maka kesalahan ini akan dapat dideteksi secara otomatis. 
Paling tidak cara ini akan mencegah kesalahan tersebut membuat bencana 
yang lebih besar, karena akan memberi peringatan kepada programmer bahwa
 ada sesuatu bug yang harus diperbaiki. Mari lihat beberapa contoh yang 
diberikan Java untuk mengatasi permasalahan ini.
Suatu array 
dibuat dengan beberapa lokasi, dimulai dengan 0 hingga ke indeks 
maksimumnya. Kita tidak dibolehkan untuk menggunakan lokasi array di 
luar rentang yang sudah dibuat. Pada Java, jika kita memaksakan untuk 
melakukan itu, sistem akan otomatis mendeteksi hal ini. Pada bahasa 
pemrograman lain seperti C dan C++, programmer diberi keleluasaan penuh 
untuk memastikan bahwa indeks array berada di dalam rentang tersebut.
Misalnya
 suatu array, A, memiliki tiga lokasi A[0], A[1], dan A[2]. Maka A[3], 
A[4], dan berikutnya adalah lokasi pada memori di luar array tersebut. 
Pada Java, apabila kita mencoba untuk menyimpan data pada A[3], Java 
akan mendeteksi ini. Program akan dihentikan saat itu juga (kecuali 
kesalahan ini "ditangkap" yang akan dibahas kemudian). Pada bahasa C 
atau C++, komputer akan diam saja dan melakukan penyimpanan di lokasi 
ini. Hasilnya akan tidak bisa diprediksi. Konsekuensinya akan jauh lebih
 berat daripada jika program berhenti (Kita akan diskusikan tentang 
tumpahan buffer di bagian ini nanti).
Pointer (penunjuk memori) 
juga merupakan kesalahan pemrograman yang paling sulit. Dalam Java, 
variabel dari suatu objek menyimpan pointer atau rujuan ke alamat memori
 di mana objek tersebut disimpan, atau isinya bisa juga 
null. Jika kita mencoba untuk menggunakan nilai 
null
 seperti layaknya rujukan ke objek sungguhan, maka sistem komputer akan 
mendeteksinya. Dalam bahasa pemrograman lain, lagi-lagi, adalah tanggung
 jawab programmer untuk mencegah digunakannya rujukan ke 
null. Pada komputer Macintosh lama, alamat 
null
 merupakan alamat ke lokasi di memori dengan alamat 0. Program dapat 
menggunakan memori di dekat alamat 0. Sayangnya, Macintosh menyimpan 
data penting tentang sistem di lokasi tersebut. Mengubah data di lokasi 
tersebut akan membuat sistem crash atau hang, bukan hanya program 
tersebut saja tetapi keseluruhan sistem operasi akan berhenti.
Kesalahan
 pointer lain adalah jika isi pointer menunjuk pada tipe data yang salah
 atau lokasi di memori yang tidak memiliki objek sama sekali. Kesalahan 
seperti ini tidak mungkin dalam bahasa Java, karena programmer tidak 
diperbolehkan untuk mengganti pointer sama sekali. Di dalam bahasa 
pemrograman lain, programmer bisa mengganti lokasi pointer ke lokasi 
lain, intinya, ke lokasi memori manapun. Jika tidak dilakukan dengan 
benar, pointer ini bisa menunjuk pada lokasi berbahaya atau menghasilkan
 sesuatu yang tidak bisa diperkirakan.
Kesalahan lain yang bisa 
terjadi pada Java adalah kebocoran memori. Pada Java, sewaktu tidak ada 
lagi pointer yang merujuk ke pada suatu objek, objek tersebut akan 
diambil oleh pemulung memori, sehingga memori tersebut dapat digunakan 
lagi oleh bagian program lain. Dalam bahasa pemrograman lain, programmer
 bertanggung jawab untuk mengembalikan memori yang tidak digunakan 
kepada sistem operasi. Jika programmer tidak melakukannya, makan memori 
yang tidak terpakai akan terakumulasi, sehingga jumlah memori yang 
tersedia akan berkurang. Ini adalah salah satu contoh masalah umum yang 
terjadi pada komputer Windows di mana banyak sekali kebocoran memori 
yang terjadi, sehingga komputer harus direstart ulang setiap beberapa 
hari.
Banyak program yang terjangkit masalah tumpahan buffer 
(buffer overflow error). Tumpahan buffer sering menjadi berita utama 
karena hal ini sering mengakibatkan kompromi masalah keamanan komputer. 
Ketika komputer menerima data dari komputer lain dari network atau 
internet misalnya, data tersebut akan disimpan dalam buffer. Buffer 
adalah bagian memori yang telah dialokasikan program untuk menyimpan 
data tersebut. Tumpahan buffer terjadi jika data yang diterima lebih 
banyak dari jumlah data yang bisa ditampung oleh buffer. Pertanyaannya 
adalah kapan ini terjadi?
Jika kesalahan ini bisa dideteksi oleh 
program atau program yang mengatur lalu lintas network, maka 
satu-satunya kemungkinan adalah pada karena kesalahan transmisi data 
pada network. Masalah utamanya terjadi ketika program tidak bisa 
mendeteksi tumpahan buffer secara benar. Dalam hal ini, software terus 
mensuplai data ke memori meskipun buffer telah terisi penuh, dan data 
lebihnya disimpan pada bagian memori yang tidak dialokasikan untuk 
buffer tersebut. Bagian memori yang tertunpah tersebut mungkin digunakan
 untuk fungsi lain. Mungkin juga digunakan untuk menyimpan data penting 
lain. Atau bahkan mungkin menyimpan kode program itu sendiri. Ini yang 
akan menjadi masalah keamanaan. MIsalnya tumpahan buffer ini menimpa 
bagian dari program. Ketika komputer mengeksekusi bagian program yang 
telah diganti, maka sebetulnya komputer akan menjalankan data yang 
diterima dari komputer lain. Data ini bisa berisi apa saja. Bisa jadi 
program untuk menghentikan komputer atau bahkan mengendalikan komputer. 
Programmer jahat yang bisa menemukan kesalahan tumpahan memori dalam 
software pengendali network bisa menggunakan lubang ini untuk 
menjalankan program-program jahatnya.
Untuk software yang ditulis 
dalam Java, kesalahan tumpahan buffer tidak dimungkinkan. Bahasa Java 
tidak mungkin menyimpan data di memori yang tidak dialokasikan 
kepadanya. Untuk bisa menyimpan data, komputer membutuhkan pointer yang 
menunjuk pada lokasi memori yang belum terpakai, atau menggunakan lokasi
 array yang berada di luar lokasi yang disediakan untuk array tersebut. 
Seperti dijelaskan sebelumnya, kedua kemungkinan tersebut tidak 
diperbolehkan sama sekali pada Java. (Akan tetapi, masih mungkin 
kesalahan seperti ini muncul pada kelas standar Java, karena beberapa 
metode pada kelas ini sebenarnya ditulis dalam bahasa C bukan Java).
Sudah
 jelas desain bahasa bisa membantu mencegah kesalahan atau membantu 
mendeteksi masalah yang mungkin terjadi. Atau dibutuhkan pengujian, 
misalnya menguji apakah pointer bernilai null. Beberapa programmer 
mungkin merasa harus mengorbankan kecanggihan dan efisiensi. Akan 
tetapi, ada banyak situasi di mana keamanan merupakan prioritas utama. 
Java didesain untuk situasi seperti ini.
Ada satu bagian di 
mana desainer Java tidak memasukkan pendeteksi masalah secara otomatis, 
yaitu perhitungan numerik. Pada Java, nilai suatu bilangan int 
dinyatakan dalam bilangan biner 32-bit. Dengan 32 bit, maka terdapat 
kurang lebih 4 milyar bilangan yang bisa dibentuk. Nilai int memiliki 
rentang antara -2147483648 hingga 2147483647. Apa yang terjadi jika 
hasil perhitungan berada di luar rentang ini? Misalnya, berapa 
2147483647 + 1? Dan berapa 2000000000 * 2? Jawaban yang benar secara 
matematis berada di luar nilai int. Contoh-contoh di atas disebut 
tumpahan bilangan bulat
 (integer overflow). Dalam banyak kasus, tumpahan bilangan bulat 
termasuk suatu kesalahan. Akan tetapi Java tidak otomatis mendeteksi 
kesalahan tersebut. Misalnya, perhitungan 2147483647 + 1 akan bernilai 
negatif -2147483648 (Apa yang terjadi sebenarnya adalah bit tambahan di 
luar bit ke-32 diabaikan. Nilai yang lebih besar dari 2147483647 akan 
"terpotong" sehingga menjadi nilai negatif. Secara matematis, hasilnya 
akan selalu merupakan sisa pembagian dari pembagian dengan 2
32).
Banyak
 kesalahan program yang disebabkan oleh kesalahan semacam ini. Program 
tersebut benar, akan tetapi tidak bisa menangani bilangan lebih besar 
daripada 32 bit. Contoh sederhana adalah kesalahan Y2K sebenarnya 
merupakan kesalahan yang mirip dengan ini.
Untuk jenis bilangan 
real seperti double, masalahnya bahkan lebih kompleks lagi. Bukan hanya 
tumpahan yang mungkin terjadi. Untuk jenis double, rentangnya berlaku 
hingga 10
308. Nilai yang lebih dari nilai ini tidak 
"terpotong" menjadi negatif. Akan tetapi ia akan diubah menjadi suatu 
konstanta yang bernilai tak berhingga. Nilai 
Double.POSITIVE_INFINITY dan 
Double.NEGATIVE_INFINITY melambangkan nilai positif tak hingga dan negatif tak hingga. Nilai spesial lainnya dari tipe data double adalah 
Doube.NaN
 atau bukan bilangan (not a number), yang melambangkan suatu nilai yang 
tidak berarti. Misalnya pembagian dengan 0 atau akar kuadrat suatu 
bilangan negatif. Kita bisa menguji apakah suatu variabel berisi bukan 
bilangan dengan memanggil fungsi yang bertipe keluaran boolean, yaitu 
Double.isNaN(x).
Untuk
 bilangan real, ada komplikasi tambahan yaitu hampir semua bilangan real
 hanya bisa dilambangkan dalam bentuk pendekatan. Bilangan real bisa 
memiliki jumlah digit di belakang koma yang tak terhingga banyaknya. 
Nilai bertipe double biasanya akurat sekitar 15 digit di belakang koma. 
Bilangan real 1/3, misalnya, berarti 0.33333333......, dan bilangan ini 
tidak bisa digantikan dengan bilangan dengan jumlah bit terbatas. 
Perhitungan dengan bilangan real biasanya memiliki kesalahan akurasi. 
Sebenarnya, jika kita kurang berhati-hati, akan menyebabkan perhitungan 
sama sekali salah. Ada bidang tertentu dalam ilmu komputer yang 
dinamakan 
analisis numerik yang berkonsentrasi pada algoritma untuk memanipulasi bilangan real..