1. Properti: getter dan setter

Ketika sebuah proyek besar sedang dikembangkan oleh lusinan pemrogram pada saat yang sama, masalah sering muncul jika mereka menangani data yang disimpan di bidang kelas secara berbeda.

Mungkin orang gagal mempelajari dokumentasi kelas secara detail, atau mungkin tidak menjelaskan setiap kasus. Akibatnya, sering terjadi situasi ketika data internal objek menjadi "rusak", membuat objek menjadi tidak valid.

Untuk menghindari situasi ini, sudah menjadi kebiasaan untuk menjadikan semua bidang kelas privat di Java . Hanya metode kelas yang dapat mengubah variabel kelas. Tidak ada metode dari kelas lain yang dapat mengakses variabel secara langsung.

Jika Anda ingin kelas lain bisa mendapatkan atau mengubah data di dalam objek kelas Anda, Anda perlu menambahkan dua metode ke kelas Anda — metode get dan metode set. Contoh:

Kode Catatan
class Person
{
   private String name;

   public Person(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }
}


privatebidang nama



Inisialisasi bidang melalui konstruktor


getName()— Metode ini mengembalikan nilai bidang nama




setName()— Metode ini mengubah nilai bidang nama

Tidak ada kelas lain yang dapat langsung mengubah nilai bidang nama. Jika seseorang perlu mendapatkan nilai dari bidang nama, mereka harus memanggil getName() metode pada suatu Personobjek. Jika beberapa kode ingin mengubah nilai bidang nama, itu perlu memanggil setName() metode pada suatu Personobjek.

Metode ini getName()juga disebut " pengambil untuk bidang nama", dan setName()metode ini disebut " penyetel untuk bidang nama".

Ini adalah pendekatan yang sangat umum. Dalam 80-90% dari semua kode Java, Anda tidak akan pernah melihat variabel publik di kelas. Sebagai gantinya, mereka akan dideklarasikan private(atau protected), dan setiap variabel akan memiliki pengambil dan penyetel publik.

Pendekatan ini membuat kode lebih panjang, tetapi lebih dapat diandalkan.

Mengakses variabel kelas secara langsung seperti memutar mobil Anda melalui garis kuning ganda : lebih mudah dan lebih cepat, tetapi jika semua orang melakukannya, keadaan akan menjadi lebih buruk bagi semua orang.

Katakanlah Anda ingin membuat kelas yang mendeskripsikan titik ( x, y). Inilah cara programmer pemula akan melakukannya:

class Point
{
   public int x;
   public int y;
}

Inilah cara seorang programmer Java yang berpengalaman akan melakukannya:

Kode
class Point {
   private int x;
   private int y;

   public Point(int x, int y) {
      this.x = x;
      this.y = y;
   }

   public int getX() {
      return x;
   }

   public void setX(int x) {
      this.x = x;
   }

   public int getY() {
      return y;
   }

   public void setY(int y) {
      this.y = y;
   }
}

Apakah kodenya lebih panjang? Niscaya.

Tapi Anda bisa menambahkan validasi parameter ke getter dan setter. Misalnya, Anda dapat memastikan bahwa xdan yselalu lebih besar dari nol (atau tidak kurang dari nol). Contoh:

Kode Catatan
class Point {
   private int x;
   private int y;

   public Point(int x, int y) {
      this.x = x < 0 ? 0 : x;
      this.y = y < 0 ? 0 : y;
   }

   public int getX() {
      return x;
   }

   public void setX(int x) {
      this.x = x < 0 ?  0 : x;
   }

   public int getY() {
      return y;
   }

   public void setY(int y) {
      this.y = y < 0 ? 0 : y;
   }
}


2. Umur objek

Anda sudah tahu bahwa objek dibuat menggunakan newoperator, tetapi bagaimana objek dihapus? Mereka tidak ada selamanya. Tidak ada cukup memori untuk itu.

Dalam banyak bahasa pemrograman, seperti C++, terdapat deleteoperator khusus untuk menghapus objek. Tapi bagaimana cara kerjanya di Jawa?

Di Jawa, semuanya diatur sedikit berbeda. Java tidak memiliki operator hapus. Apakah ini berarti objek tidak dihapus di Jawa? Tidak, mereka dihapus, tentu saja. Jika tidak, aplikasi Java akan cepat kehabisan memori, dan tidak akan ada pembicaraan tentang program yang berjalan tanpa gangguan selama berbulan-bulan.

Di Java, penghapusan objek sepenuhnya otomatis. Mesin Java itu sendiri menangani penghapusan objek. Proses ini disebut pengumpulan sampah, dan mekanisme yang mengumpulkan sampah disebut pengumpul sampah ( GC ).

Jadi bagaimana mesin Java tahu kapan harus menghapus objek?

Pengumpul sampah membagi semua objek menjadi "dapat dijangkau" dan "tidak dapat dijangkau". Jika setidaknya ada satu referensi ke suatu objek, itu dianggap dapat dijangkau. Jika tidak ada variabel yang merujuk ke suatu objek, maka objek tersebut dianggap tidak dapat dijangkau dan dinyatakan sebagai sampah, yang artinya dapat dihapus.

Di Java, Anda tidak bisa membuat referensi ke objek yang sudah ada — Anda hanya bisa menetapkan referensi yang sudah Anda miliki. Jika kita menghapus semua referensi ke suatu objek, maka itu akan hilang selamanya.

Referensi melingkar

Logika itu terdengar bagus sampai kita menemukan contoh tandingan sederhana: misalkan kita memiliki dua objek yang saling merujuk (menyimpan referensi satu sama lain). Tidak ada objek lain yang menyimpan referensi ke objek ini.

Objek-objek ini tidak dapat diakses dari kode, tetapi masih direferensikan.

Inilah sebabnya pengumpul sampah membagi objek menjadi dapat dijangkau dan tidak dapat dijangkau daripada "direferensikan" dan "tidak direferensikan".

Objek yang dapat dijangkau

Pertama, objek yang 100% hidup ditambahkan ke daftar yang dapat dijangkau. Misalnya, utas saat ini ( Thread.current()) atau konsol InputStream ( System.in).

Kemudian daftar objek yang dapat dijangkau diperluas untuk menyertakan objek yang direferensikan oleh set awal objek yang dapat dijangkau. Kemudian diperluas lagi untuk menyertakan objek yang direferensikan oleh himpunan yang diperbesar ini, dan seterusnya.

Artinya, jika ada beberapa objek yang hanya merujuk satu sama lain, tetapi tidak ada cara untuk menjangkaunya dari objek yang dapat dijangkau, maka objek tersebut akan dianggap sampah dan akan dihapus.


3. Pengumpulan sampah

Fragmentasi memori

Poin penting lainnya terkait penghapusan objek adalah fragmentasi memori. Jika Anda terus-menerus membuat dan menghapus objek, memori akan segera terfragmentasi: area memori yang terisi akan diselingi dengan area memori kosong.

Akibatnya, kita dapat dengan mudah masuk ke situasi di mana kita tidak dapat membuat objek besar (misalnya, array dengan sejuta elemen), karena tidak ada banyak memori kosong. Dengan kata lain, mungkin ada memori bebas, bahkan banyak, tetapi mungkin tidak ada blok besar memori bebas yang berdekatan.

Pengoptimalan memori (defragmentasi)

Mesin Java memecahkan masalah ini dengan cara tertentu. Ini terlihat seperti ini:

Memori dibagi menjadi dua bagian. Semua objek dibuat (dan dihapus) hanya dalam setengah memori. Saat tiba waktunya untuk membersihkan lubang di memori, semua objek di babak pertama akan disalin ke babak kedua. Tapi mereka disalin tepat di samping satu sama lain sehingga tidak ada lubang.

Prosesnya kira-kira seperti ini:

Langkah 1: Setelah membuat objek

Pengumpulan sampah di Jawa

Langkah 2: Munculnya "lubang"

Pengumpulan sampah di Jawa 2

Langkah 3: Penghapusan "lubang"

Pengumpulan sampah di Jawa 3

Dan itulah mengapa Anda tidak perlu menghapus objek. Mesin Java hanya menyalin semua objek yang dapat dijangkau ke lokasi baru, dan membebaskan seluruh area memori tempat objek dulu disimpan.