Dalam pemrograman Java, salah satu konsep yang penting untuk dipahami adalah perbedaan antara objek mutable dan immutable. Istilah ini mungkin terdengar teknis, tapi mereka sangat relevan dalam pengembangan aplikasi karena bisa memengaruhi performa, keamanan, dan bahkan bug di aplikasi Anda. Artikel ini akan membahas dengan cara yang mudah dipahami apa itu mutable dan immutable, perbedaannya, contohnya, serta studi kasus yang relevan dalam konteks pemrograman sehari-hari. Mari kita bahas topik ini.
Apa itu Mutable?
Mutable berarti "dapat diubah". Dalam konteks Java, objek mutable adalah objek yang bisa dimodifikasi setelah ia diciptakan (instansiasi). Misalnya, jika kita membuat sebuah objek StringBuilder, kita dapat terus mengubah isi dari objek ini tanpa perlu membuat objek baru. Konsep mutable sangat umum dan sering digunakan dalam aplikasi yang memerlukan perubahan data secara berulang.
Contoh Mutable Object
Mari kita lihat contoh penggunaan objek mutable dalam Java.
StringBuilder sb = new StringBuilder("Halo");
sb.append(", Dunia!"); // Memodifikasi isi StringBuilder tanpa membuat objek baru
System.out.println(sb); // Output: Halo, Dunia!
Dalam contoh di atas, kita membuat objek StringBuilder dengan teks "Halo". Kemudian, kita menambahkan ", Dunia!" ke dalam objek yang sama. Alih-alih membuat objek baru setiap kali kita melakukan perubahan, StringBuilder memperbarui data di dalam objek yang sama.
Apa itu Immutable?
Immutable berarti "tidak dapat diubah". Dalam Java, objek immutable adalah objek yang isinya tidak bisa diubah setelah diciptakan. Setiap kali kita mencoba memodifikasi objek immutable, kita sebenarnya menciptakan objek baru. Salah satu contoh paling umum dari objek immutable di Java adalah String.
Contoh Immutable Object
Berikut adalah contoh dari objek immutable menggunakan kelas String:
public void doImmutableString() {
String str = "Halo";
str = str.concat(", Dunia!"); // Menciptakan objek baru
System.out.println(str); // Output: Halo, Dunia!
}
Di sini, ketika kita melakukan concat untuk menambahkan kata ", Dunia!" ke dalam string "Halo". Code di atas sebenarnya tidak mengubah String str yang pertama kali dibuat. Sebaliknya, Java membuat objek String baru yang berisi "Halo, Dunia!" dan mengarahkan variabel str ke objek baru tersebut.
Cetak alamat memory untuk membuktikan muttable dan Immutable
Melakukan cetak alamat memori dapat membantu menunjukkan sifat mutable atau immutable, tetapi itu bukan satu-satunya bukti. Alamat memori bisa memberikan petunjuk mengenai apakah objek berubah atau tidak ketika dimodifikasi. Mari kita pahami lebih lanjut bagaimana ini bisa digunakan sebagai indikator:
Untuk objek mutable, ketika Anda mengubah nilai dari objek, alamat memori tetap sama. Ini menunjukkan bahwa objek yang sama di memori telah diubah secara langsung.
Contoh dengan StringBuilder (Mutable):
public void printAddressStringBuilder() {
StringBuilder sb = new StringBuilder("Halo");
System.out.println(System.identityHashCode(sb)); // Cetak alamat memori, ex: 1277181601
sb.append(", Dunia!"); // Modifikasi objek
System.out.println(System.identityHashCode(sb)); // Cetak alamat memori lagi, ex: 127718160
}
Hasilnya alamat memori yang dicetak akan sama sebelum dan sesudah .append(). Ini membuktikan bahwa objek StringBuilder bersifat mutable, karena perubahan terjadi tanpa menciptakan objek baru.
Untuk objek immutable seperti String, ketika Anda memodifikasi objek (misalnya, dengan menambahkan teks) alamat memori berubah. Hal ini menunjukkan bahwa objek baru dibuat di memori.
Contoh dengan String (Immutable):
public void printAddressString() {
String str = "Halo";
System.out.println(System.identityHashCode(str)); // Cetak alamat memori
str = str.concat(", Dunia!"); // Modifikasi objek, ex : 41903949
System.out.println(System.identityHashCode(str)); // Cetak alamat memori lagi, ex : 488970385
}
Hasilnya alamat memori yang dicetak akan berbeda sebelum dan sesudah concat(). Ini menunjukkan bahwa String bersifat immutable, karena modifikasi tidak mengubah objek asli, melainkan menciptakan objek baru dengan alamat memori yang berbeda.
Kenapa Ini Penting?
Mencetak alamat memori membantu memperlihatkan apakah objek yang Anda gunakan diubah langsung (mutable) atau dibuat objek baru (immutable). Ketika alamat memori berbeda setelah modifikasi, ini menunjukkan bahwa objek tersebut immutable. Namun, jika alamat memori sama setelah perubahan, ini menunjukkan bahwa objek tersebut mutable.
Mengapa Harus Peduli dengan Mutable dan Immutable?
Pemahaman tentang mutable dan immutable sangat penting karena mereka memiliki implikasi yang besar dalam beberapa aspek pemrograman:
- Keamanan Data (Thread Safety). Objek immutable lebih aman digunakan dalam lingkungan multithreading. Karena objek immutable tidak dapat diubah, mereka tidak bisa dimodifikasi secara tidak sengaja oleh thread lain, sehingga mengurangi risiko terjadinya race condition atau bug yang sulit dideteksi.
- Efisiensi Memori. Objek immutable seperti String dikelola secara khusus oleh Java melalui konsep yang disebut String pool. Ini berarti bahwa setiap kali Anda membuat string yang sama, Java akan merujuk ke objek yang sama di memori, daripada membuat objek baru, yang dapat menghemat memori.
- Performa. Meskipun objek mutable sering kali lebih cepat untuk diubah daripada immutable, dalam beberapa kasus, penggunaan objek immutable dapat meningkatkan performa karena Java dapat melakukan optimasi tertentu pada objek yang tidak berubah.
- Desain yang Lebih Jelas. Objek immutable lebih mudah untuk dipahami dan digunakan karena mereka tidak memiliki state yang bisa berubah-ubah. Ini membantu menghindari bug yang sulit dilacak yang disebabkan oleh perubahan state objek secara tidak sengaja.
Mutable vs Immutable dalam Koleksi Data
Java menyediakan berbagai macam koleksi data, seperti ArrayList, HashSet, dan HashMap. Secara default, koleksi-koleksi ini adalah mutable, yang artinya kita bisa menambahkan, menghapus, atau memodifikasi elemen di dalamnya. Namun, ada juga cara untuk membuat koleksi-koleksi ini menjadi immutable dengan menggunakan metode Collections.unmodifiableList, Collections.unmodifiableSet, dan Collections.unmodifiableMap.
Contoh Penggunaan Koleksi Immutable
public void doAddImmutableCollection(){
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> immutableList = Collections.unmodifiableList(list);
list.add("D"); // Berhasil
immutableList.add("E"); // Error: UnsupportedOperationException
}
Hasil
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1067)
at sufyan97_blog/sufyan97_blog.LearnMutImutable.doAddImmutableCollection(LearnMutImutable.java:51)
at sufyan97_blog/sufyan97_blog.LearnMutImutable.main(LearnMutImutable.java:15)
Pada contoh di atas, kita membuat list mutable yang bisa dimodifikasi, namun setelah mengubahnya menjadi immutable dengan Collections.unmodifiableList, setiap percobaan untuk memodifikasinya akan menghasilkan UnsupportedOperationException. Ini berguna saat Anda ingin memastikan bahwa data tertentu tidak diubah setelah diinisialisasi.
Mutable dan Immutable dalam Desain Kelas
Saat merancang kelas Anda sendiri, Anda juga harus memutuskan apakah kelas tersebut sebaiknya mutable atau immutable. Sebagai panduan umum:
- Gunakan mutable objects. ketika Anda memerlukan objek yang sering berubah, seperti kelas yang mengelola buffer atau koleksi data.
- Gunakan immutable objects ketika Anda ingin membuat objek yang aman dari perubahan, terutama jika digunakan dalam konteks multithreading atau sebagai konstanta.
Contoh Kelas Immutable
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Dalam kelas Point di atas, kita menggunakan kata kunci final pada kelas dan field untuk memastikan bahwa nilai x dan y tidak bisa diubah setelah objek dibuat. Ini adalah contoh sederhana dari kelas immutable yang aman untuk digunakan di berbagai tempat tanpa khawatir terjadi modifikasi yang tidak disengaja.
Kesimpulan
Memahami konsep mutable dan immutable dalam Java adalah keterampilan penting yang dapat membantu Anda menulis kode yang lebih aman, efisien, dan mudah dipahami. Objek mutable memberikan fleksibilitas dalam memodifikasi data secara langsung, namun bisa menimbulkan risiko dalam situasi multithreading atau ketika keamanan data sangat penting. Di sisi lain, objek immutable menawarkan stabilitas dan keamanan yang lebih baik, terutama dalam aplikasi yang melibatkan banyak thread atau memerlukan optimasi memori.
Pilihan antara mutable dan immutable bukanlah hitam dan putih. Sebagai pengembang, Anda perlu mempertimbangkan situasi spesifik dan kebutuhan aplikasi Anda sebelum memutuskan mana yang paling cocok.
Print alamat memori dapat menjadi indikator yang baik untuk membuktikan apakah suatu objek bersifat mutable atau immutable. Namun, ini bukan satu-satunya bukti, melainkan cara tambahan untuk memahami bagaimana Java menangani objek-objek tersebut di memori. Bukti utama dari konsep immutable di Java adalah perilaku kelas, metode yang tidak mengubah state internal, dan penggunaan kata kunci seperti final.
Anda bisa melihat codenya di github berikut.
Referensi
- https://www.baeldung.com/java-mutable-vs-immutable-objects diakses pada 7 September 2024.
- https://jfeatures.com/blog/immutable_records diakses pada 8 September 2024,
- https://medium.com/javarevisited/how-do-you-know-if-a-java-collection-is-mutable-or-immutable-b397dfc5d231 diakses pada 8 September 2024.
Posting Komentar untuk "Mengenal Objek Mutable dan Immutable pada Java Sebuah Konsep Penting untuk Dipahami"
Berilah komentar, saran, dan kritik dengan bijak