Objek yang Tidak Berubah di Java

1. Ikhtisar

Dalam tutorial ini, kita akan mempelajari apa yang membuat objek tidak bisa diubah, bagaimana mencapai keabadian di Java, dan keuntungan apa yang didapat dengan melakukannya.

2. Apa itu Objek yang Tidak Berubah?

Objek yang tidak dapat diubah adalah objek yang keadaan internalnya tetap konstan setelah seluruhnya dibuat .

Artinya, API publik dari objek yang tidak dapat diubah menjamin kita bahwa ia akan berperilaku dengan cara yang sama selama masa pakainya.

Jika kita melihat kelas String , kita dapat melihat bahwa meskipun API-nya tampaknya memberi kita perilaku yang bisa berubah dengan metode replace , String asli tidak berubah:

String name = "baeldung"; String newName = name.replace("dung", "----"); assertEquals("baeldung", name); assertEquals("bael----", newName);

API memberi kita metode hanya-baca, itu tidak boleh menyertakan metode yang mengubah keadaan internal objek.

3. Kata kunci terakhir di Jawa

Sebelum mencoba mencapai kekekalan di Java, kita harus berbicara tentang kata kunci terakhir .

Di Java, variabel dapat berubah secara default, artinya kita dapat mengubah nilai yang dimilikinya .

Dengan menggunakan kata kunci terakhir saat mendeklarasikan variabel, compiler Java tidak akan membiarkan kita mengubah nilai variabel itu. Sebaliknya, ini akan melaporkan kesalahan waktu kompilasi:

final String name = "baeldung"; name = "bael...";

Perhatikan bahwa final hanya melarang kita mengubah referensi yang dipegang variabel, itu tidak melindungi kita dari mengubah keadaan internal objek yang dirujuknya dengan menggunakan API publiknya:

final List strings = new ArrayList(); assertEquals(0, strings.size()); strings.add("baeldung"); assertEquals(0, strings.size());

AssertEquals kedua akan gagal karena menambahkan elemen ke daftar mengubah ukurannya, oleh karena itu, ini bukan objek yang tidak dapat diubah.

4. Kekekalan di Jawa

Sekarang kita tahu bagaimana menghindari perubahan pada konten variabel, kita bisa menggunakannya untuk membangun API dari objek yang tidak bisa diubah.

Membangun API dari objek yang tidak dapat diubah mengharuskan kami untuk menjamin bahwa status internalnya tidak akan berubah tidak peduli bagaimana kami menggunakan API-nya.

Sebuah langkah maju ke arah yang benar adalah menggunakan final saat mendeklarasikan atributnya:

class Money { private final double amount; private final Currency currency; // ... }

Perhatikan bahwa Java menjamin kita bahwa nilai jumlah tidak akan berubah, demikian halnya dengan semua variabel tipe primitif.

Namun, dalam contoh kami, kami hanya dijamin bahwa mata uang tidak akan berubah, jadi kami harus mengandalkan API Mata Uang untuk melindungi dirinya dari perubahan .

Seringkali, kita membutuhkan atribut sebuah objek untuk menampung nilai-nilai khusus, dan tempat untuk menginisialisasi keadaan internal dari objek yang tidak bisa diubah adalah konstruktornya:

class Money { // ... public Money(double amount, Currency currency) { this.amount = amount; this.currency = currency; } public Currency getCurrency() { return currency; } public double getAmount() { return amount; } }

Seperti yang telah kami katakan sebelumnya, untuk memenuhi persyaratan API yang tidak dapat diubah, kelas Uang kami hanya memiliki metode hanya-baca.

Dengan menggunakan API refleksi, kita dapat merusak keabadian dan mengubah objek yang tidak bisa diubah. Namun, refleksi melanggar API publik objek yang tidak dapat diubah, dan biasanya, kita harus menghindari melakukan ini.

5. Manfaat

Karena status internal objek yang tidak berubah tetap konstan dalam waktu, kami dapat membagikannya dengan aman di antara beberapa utas .

Kita juga dapat menggunakannya secara bebas, dan tidak ada objek yang mereferensikannya akan melihat perbedaan apa pun, kita dapat mengatakan bahwa objek yang tidak dapat diubah adalah bebas efek samping .

6. Kesimpulan

Objek yang tidak dapat diubah tidak mengubah status internalnya pada waktunya, objek tersebut aman untuk thread dan bebas efek samping. Karena properti tersebut, objek yang tidak dapat diubah juga sangat berguna saat menangani lingkungan multi-utas.

Anda dapat menemukan contoh yang digunakan dalam artikel ini di GitHub.