TL; DR
Java meng-cache kotak instance Integer dari -128
ke 127
. Karena Anda menggunakan ==
untuk membandingkan referensi objek dan bukan nilai , hanya objek cache yang akan cocok. Bekerja dengan long
nilai primitif tanpa kotak atau gunakan .equals()
untuk membandingkan Long
objek Anda .
Versi panjang (permainan kata-kata)
Mengapa ada masalah dalam membandingkan variabel panjang dengan nilai lebih dari 127? Jika tipe data dari variabel di atas adalah primitif (panjang) maka kode berfungsi untuk semua nilai.
Java menyimpan cache instance objek Integer dari kisaran -128 hingga 127 . Yang mengatakan:
- Jika Anda menyetel ke N variabel panjang nilai
127
( cache ), instance objek yang sama akan ditunjukkan oleh semua referensi. (N variabel, 1 contoh)
- Jika Anda menyetel ke N variabel panjang nilainya
128
( tidak di-cache ), Anda akan memiliki instance objek yang ditunjukkan oleh setiap referensi. (N variabel, N contoh)
Itulah mengapa ini:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Keluaran ini:
benar
salah
Untuk nilai 127L , karena kedua referensi (val1 dan val2) menunjuk ke instance objek yang sama dalam memori (cache), ia mengembalikan true
.
Di sisi lain, untuk nilai 128 , karena tidak ada contoh untuk itu yang di-cache dalam memori, yang baru dibuat untuk setiap tugas baru untuk nilai kotak, menghasilkan dua contoh yang berbeda (ditunjukkan oleh val3 dan val4) dan kembali false
pada perbandingan di antara mereka.
Itu terjadi semata-mata karena Anda membandingkan dua Long
referensi objek , bukan long
nilai primitif, dengan ==
operator. Jika bukan karena mekanisme Cache ini, perbandingan ini akan selalu gagal, jadi masalah sebenarnya di sini adalah membandingkan nilai kotak dengan ==
operator.
Mengubah variabel ini menjadi long
tipe primitif akan mencegah hal ini terjadi, tetapi jika Anda perlu menyimpan kode Anda menggunakan Long
objek, Anda dapat membuat perbandingan ini dengan aman dengan pendekatan berikut:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(Diperlukan pemeriksaan nol yang tepat, bahkan untuk coran)
IMO , itu selalu merupakan ide yang baik untuk tetap menggunakan metode .equals () saat berurusan dengan perbandingan Objek.
Tautan referensi:
.longValue()
.Membandingkan non-primitif (alias Objek) di Java dengan
==
membandingkan referensi mereka, bukan nilainya.Long
adalah kelas dan dengan demikianLong
nilai adalah Objek.Masalahnya adalah Java Developers ingin orang menggunakan
Long
seperti dululong
untuk menyediakan kompatibilitas, yang mengarah pada konsep autoboxing, yang pada dasarnya adalah fitur, yanglong
-values akan diubah menjadiLong
-Objects dan sebaliknya sesuai kebutuhan. Perilaku autoboxing tidak selalu dapat diprediksi, karena tidak ditentukan sepenuhnya.Jadi agar aman dan memiliki hasil yang dapat diprediksi selalu gunakan
.equals()
untuk membandingkan objek dan jangan mengandalkan autoboxing dalam hal ini:sumber