Sunday, March 11, 2018

Tipe Data, Variabel, dan Array Bagian 2



Variabel
Variabel adalah unit penyimpanan dasar pada sebuah program Java. Variabel didefinisikan menggunakan kombinasi dari pengenal, tipe data, dan penginisialisasi opsional. Selain itu, variabel juga memiliki skop, yang mendefinisikan visibilitas dan masa-berlakunya. Elemen-elemen ini akan didiskusikan berikut ini.


Mendeklarasikan Sebuah Variabel
Dalam Java, semua variabel harus dideklarasikan sebelum ia digunakan. Bentuk umum dari sebuah pendeklarasian variabel ditunjukkan berikut:

tipe_data pengenal [= nilai][, pengenal[=nilai]];

Di sini, tipe_data adalah salah satu tipe data dasar Java, atau nama sebuah kelas atau antarmuka. (Kelas dan antarmuka akan didiskusikan nanti pada buku ini). Komponen pengenal adalah nama variabel. Anda dapat menginisialisasi variabel dengan memberikan sebuah tanda sama-dengan dan sebuah nilai. Anda perlu mengingat bahwa ekspresi inisialisasi harus menghasilkan sebuah nilai dengan tipe data sama (atau kompatibel) dengan tipe data dari variabel. Untuk mendeklarasikan lebih dari satu variabel dengan tipe data sama, Anda bisa menggunakan koma untuk memisahkannya.

Berikut adalah beberapa contoh pendeklarasian variabel dengan sejumlah tipe data. Perhatikan bahwa beberapa di antaranya mencakup inisialisasi.

int a, b, c;   // mendeklarasikan tiga integer, a, b, dan c.
int d = 3, e, f = 5;  // mendeklarasikan tiga integer lain,
           // dengan menginisialisasi d dan f.
byte z = 22;   // menginisialisasi z.
double pi = 3.14159;  // mendeklarasikan sebuah pendekatan atas pi.
char x = 'x';   // variabel x memiliki nilai 'x'.


Inisialisasi Dinamis
Meskipun contoh-contoh sebelumnya hanya menggunakan konstanta sebagai penginisialisasi, Java membolehkan variabel untuk diinisialisasi secara dinamis, menggunakan sembarang ekspresi yang valid.

Sebagai contoh, berikut adalah sebuah program pendek yang menghitung panjang dari sisi miring dari sebuah segitiga:

//Mendemonstrasikan inisialisasi dinamis
public class InisialisasiDinamis {
   public static void main(String args[]) {
      double a = 3.0, b = 4.0;
  
      // c diinisialisasi secara dinamis
      double c = Math.sqrt(a * a + b * b);
  
      System.out.println("Sisi-miring segitiga = " + c);
   }
}

Di sini, tiga variabel lokal: a, b, dan c, dideklarasikan. Dua variabel pertama, a dan b, diinisialisasi dengan konstanta. Namun, variabel c diinisialisasi secara dinamis menggunakan panjang sisi-miring segitiga (menggunakan rumus Pythagoras). Program menggunakan metode pustaka Java, sqrt(), yang merupakan anggota dari kelas Math, untuk menghitung akar kuadrat dari argumennya. Hal kunci di sini adalah bahwa ekspresi inisialisasi dapat berupa elemen yang valid, termasuk pemanggilan terhadap metode, variabel lain, atau literal.


Skop dan Masa Hidup Variabel
Sejauh ini, semua variabel yang digunakan dideklarasikan di awal dari metode main(). Namun, Java membolehkan agar variabel dideklarasikan di dalam sembarang blok kode. Seperti dijelaskan pada Bab 1, sebuah blok kode diawali dengan kurung kurawal pembuka dan diakhiri dengan kurung kurawal penutup. Blok kode mendefinisikan sebuah skop. Jadi, setiap kali Anda mengawali sebuah blok kode baru, Itu berarti bahwa Anda sedang menciptakan sebuah skop baru. Skop menentukan apakah objek visibel atau dapat diakses oleh bagian lain dari program Anda. Skop juga menentukan masa berlaku dari objek tersebut.

Banyak bahasa pemrograman komputer lain mendefinisikan dua kategori skop: global dan lokal. Namun, kedua skop tradisional ini tidak sesuai dengan model berorientasi-objek pada Java. Pada Java, dua skop utama adalah skop yang didefinisikan oleh sebuah kelas dan skop yang didefinisikan oleh sebuah metode.

Skop yang didefinisikan oleh sebuah metode diawali dengan kurung kurawal pembukanya. Namun, jika metode tersebut memiliki parameter-parameter, maka parameter-parameter tersebut juga berada di dalam skop metode.

Sebagai aturan umum, variabel yang dideklarasikan di dalam sebuah skop tidak akan visible (tidak dapat diakses) oleh kode yang didefinisikan di luar skop itu. Jadi, ketika Anda mendeklarasikan sebuah variabel di dalam sebuah skop, maka Anda sedang melokalisasi variabel itu dan melindunginya agar tidak bisa diakses dan/atau dimodifikasi oleh pihak yang tak berwenang. Jadi, aturan skop merupakan pondasi untuk enkapsulasi.

Skop dapat dibuat bersarang di dalam skop lain. Sebagai contoh, setiap kali Anda menciptakan sebuah blok kode, Anda sedang menciptakan skop bersarang yang baru. Ketika ini terjadi, skop terluar mangapit skop sebelah dalam. Ini berarti bahwa objek yang didefinisikan pada skop luar dapat diakses oleh kode yang ada pada skop sebelah dalam. Hal ini tidak berlaku sebaliknya. Objek yang dideklarasikan di dalam skop sebelah dalam tidak dapat diakses oleh kode yang ada di luarnya.

Untuk memahami pengaruh dari skop bersarang, perhatikan program berikut:

//Mendemonstraskan skop blok
public class Skop {
   public static void main(String args[]) {
      int x; // bisa diakses oleh semua kode di dalam main()
  
      x = 10;
      if(x == 10) { // memulai skop baru
         int y = 20; // known only to this block
  
         // x dan y dapat diakses di sini.
         System.out.println("x dan y: " + x + " " + y);
         x = y * 2;
      }
      // y = 100; // Error! y tidak dikenali di sini

      // x masih dikenali di sini.
      System.out.println("x = " + x);
   }
}

Seperti yang dinyatakan oleh komentar program, variabel x dideklarasikan di awal dari skop main() dan dapat diakses oleh semua kode yang ada di dalam main(). Di dalam blok if, variabel y dideklarasikan. Karena sebuah blok mendefinisikan skop baru, maka y hanya dapat diakses dari dalam bloknya. Inilah mengapa di luar bloknya, baris kode y = 100; dijadikan komentar. Jika Anda menghapus simbol komentar tersebut, maka error kompilasi akan terjadi, karena y tidak bisa diakses oleh kode di luar bloknya. Di dalam blok if, x dapat digunakan karena kode di dalam sebuah blok (sebuah blok bersarang) memiliki akses terhadap variabel yang dideklarasikan oleh skop yang mengapitnya atau membungkusnya.

Di dalam sebuah blok kode, variabel dapat dideklarasikan pada sembarang titik, tetapi hanya bisa digunakan setelah dideklarasikan. Jadi, jika Anda mendefinisikan sebuah variabel di awal sebuah metode, maka variabel tersebut dapat diakses oleh semua kode di dalam metode tersebut. Sebaliknya, jika Anda mendeklarasikan sebuah variabel di akhir suatu blok, maka variabel itu tidak berguna, karena tidak ada kode yang bisa mengaksesnya. Sebagai contoh, potongan kode berikut tak valid karena cacah tidak bisa digunakan sebelum titik pendeklarasiannya:

//Fragmen kode ini salah!
cacah = 100;   //Variabel cacah tidak bisa digunakan sebelum dideklarasikan
int cacah;

Di sini, ada hal penting lain untuk diingat: variabel diciptakan ketika skopnya mulai dieksekusi, dan variabel dibuang atau dihancurkan ketika skopnya selesai dieksekusi. Ini berarti bahwa sebuah variabel tidak akan bisa memuat nilainya ketika skopnya selesai dieksekusi. Oleh karena itu, variabel yang dideklarasikan di dalam sebuah metode tidak akan mempertahankan nilainya di antara pemanggilan-pemanggilan metode. Selain itu, sebuah variabel yang dideklarasikan di dalam sebuah blok akan kehilangan nilainya ketika blok tersebut selesai dieksekusi. Jadi, masa berlaku dari sebuah variabel dikekang di dalam skopnya.

Jika sebuah deklarasi variabel melibatkan penginisialisasi, maka variabel itu akan diinisialisasi ulang setiap kali blok kode dimana ia dideklarasikan dieksekusi. Sebagai contoh, perhatikan program berikut:

//Mendemonstrasikan masa hidup variabel
public class MasaHidup {
   public static void main(String args[]) {
      int x;

      for(x = 0; x < 3; x++) {
         int y = -1; // y diinisialisasi setiap kali blok dieksekusi
         System.out.println("y = " + y); // ini selalu menampilkan -1
  
         y = 100;
         System.out.println("y sekarang = " + y);
      }
   }
}

Keluaran yang dihasilkan program ini diberikan berikut:

y = -1
y sekarang = 100
y = -1
y sekarang = 100
y = -1
y sekarang = 100

Seperti yang dapat Anda lihat, y diinisialisasi ulang dengan -1 setiap kali loop for dieksekusi. Meskipun variabel y ditugasi nilai 100, nilai ini hilang.

Satu hal penting terakhir: Meskipun blok dapat dibuat bersarang, Anda tidak bisa mendeklarasikan sebuah variabel untuk memiliki nama sama dengan variabel yang ada di skop terluar. Sebagai contoh, program berikut tidak valid:

//Program ini tidak bisa dikompilasi
public class ErrorSkop {
   public static void main(String args[]) {
      int coklat = 1;
      
      { // menciptakan sebuah skop baru
         int coklat = 2; // Error kompilasi – coklat sudah didefinisikan!
      }
   }
}


Konversi Tipe Otomatis dan Konversi Tipe Paksa (Casting)
Jika Anda memiliki pengalaman pemrograman sebelumnya, Anda tentu telah mengetahui bahwa adalah hal umum untuk menugaskan sebuah nilai dengan tipe data tertentu kepada sebuah variabel dengan tipe data lain. Jika kedua tipe tersebut kompatibel, Java akan melakukan konversi tipe secara otomatis. Sebagai contoh, Anda bisa menugaskan sebuah nilai int kepada sebuah variabel long. Namun, tidak semua tipe data kompatibel. Jadi, tidak semua konversi tipe data bisa dilakukan secara implisit oleh kompilator Java. Sebagai contoh, tidak ada konversi tipe data otomatis yang didefinisikan dari double ke byte. Untunglah, Anda masih dimungkinkan untuk melakukan konversi tipe data antara tipe-tipe data yang tak kompatibel. Untuk melakukannya, Anda melakukan konversi paksa, yang melakukan konversi eksplisit di antara tipe-tipe data yang tak kompatibel tersebut.


Konversi Tipe Data Otomatis Pada Java
Ketika sebuah nilai dengan tipe data tertentu ditugaskan kepada variabel dengan tipe data lain, maka konversi tipe data otomatis akan terjadi jika memenuhi dua syarat berikut:
  • Kedua tipe data kompatibel.
  • Tipe data target lebih besar dari tipe data sumber
Ketika kedua syarat ini dipenuhi, konversi pelebaran akan terjadi. Sebagai contoh, tipe data int selalu cukup besar untuk memuat semua nilai byte yang valid, jadi statemen konversi eksplisit tidak diperlukan.

Pada konversi pelebaran, tipe-tipe data numerik, termasuk tipe data integer dan tipe data titik-mengambang, kompatibel satu sama lain. Namun, tidak ada konversi otomatis dari tipe numerik char atau boolean. Selain itu, char dan boolean tidak kompatibel satu sama lain.

Seperti disebutkan sebelumnya, Java juga melakukan konversi tipe data otomatis ketika menyimpan sebuah konstanta literal integer menjadi variabel dengan tipe data byte, short, long, atau char.


Konversi Tipe Data Tak Kompatibel
Meskipun konversi tipe data secara otomatis dapat dilakukan, ada sejumlah kejadian dimana hal itu tidak bisa dilakukan. Sebagai contoh, bagaimana jika Anda ingin menugaskan sebuah nilai int kepada sebuah variabel byte? Konversi ini tidak akan dilakukan secara otomatis oleh kompilator Java, karena ukuran byte lebih kecil dari int. Jenis konversi semacam ini dikenal sebagai konversi penyempitan, karena Anda secara eksplisit sedang mempersempit nilai sehingga nilai tersebut dapat dimuat oleh tipe data target.

Untuk menciptakan konversi antara tipe-tipe data tak-kompatibel, Anda memerlukan sebuah cast. Cast adalah konversi tipe data eksplisit. Konversi ini memiliki bentuk umum berikut:

(tipe_data_target) nilai

Di sini, tipe_data_target menetapkan tipe data yang diinginkan dari nilai. Sebagai contoh, potongan kode berikut mengkonversi secara eksplisit (cast) sebuah int menjadi sebuah byte. Jika nilai integer yang akan dikonversi lebih besar dari rentang tipe data byte, maka nilainya akan menjadi modulo (sisa pembagian integer) dari rentang byte.

int a;
byte b;
//…
b = (byte) a;

Konversi tipe data yang berbeda akan terjadi ketika sebuah nilai titik-mengambang ditugaskan kepada sebuah tipe data integer. Yang akan terjadi adalah pemotongan. Seperti Anda ketahui, integer tidak memiliki komponen pecahan atau fraksional. Jadi, ketika sebuah nilai titik-mengambang ditugaskan kepada tipe integer, komponen fraksional akan dibuang. Sebagai contoh, jika nilai 1.23 ditugaskan kepada sebuah integer, maka nilai yang dihasilkan adalah 1. Sisanya, 0.23, akan dibuang. Tentu, jika ukuran dari komponen bilangan bulat terlalu besar untuk dimuat ke dalam tipe data target, maka nilai itu akan direduksi secara modulo terhadap rentang tipe data target.

Program berikut mendemonstrasikan sejumlah konversi tipe data yang memerlukan cast:

//Mendemonstrasikan konversi tipe
public class Konversi {
   public static void main(String args[]) {
      byte b;
      int i = 257;
      double d = 323.142;
  
      System.out.println("\nKonversi int menjadi byte.");
      b = (byte) i;
      System.out.println("i dan b " + i + " " + b);
      
      System.out.println("\nKonversi dari double menjadi int.");
      i = (int) d;
      System.out.println("d dan i " + d + " " + i);
  
      System.out.println("\nKonversi dari double menjadi byte.");
      b = (byte) d;
      System.out.println("d and b " + d + " " + b);
   }
}

Program ini menghasilkan keluaran berikut:

Konversi int menjadi byte.
i dan b 257 1

Konversi dari double menjadi int.
d dan i 323.142 323

Konversi dari double menjadi byte.
d and b 323.142 67

Perhatikan tiap konversi yang terjadi. Ketika nilai 257 dikonversi menjadi sebuah variabel byte, hasilnya adalah sisa pembagian 257 oleh 256 (rentang tipe data byte), yaitu 1 pada kasus ini. Ketika d dikonversi menjadi sebuah int, komponen fraksionalnya dibuang. Ketika d dikonversi menjadi sebuah byte, komponen fraksionalnya hilang, dan nilainya direduksi dengan modulo 256, yang menghasilkan 67.

Selanjutnya  >>>

No comments: