Saya tidak tahu mengapa baris kode ini mengembalikan nilai yang berbeda:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
Outputnya adalah:
true
false
true
Mengapa yang pertama kembali true
dan yang kedua kembali false
? Apakah ada sesuatu yang berbeda yang tidak saya ketahui antara 127
dan 128
? (Tentu saja aku tahu itu 127
< 128
.)
Juga, mengapa yang ketiga kembali true
?
Saya telah membaca jawaban dari pertanyaan ini , tetapi saya masih belum mengerti bagaimana ia dapat kembali true
, dan mengapa kode di baris kedua kembali false
.
java
integer
comparison
DnR
sumber
sumber
.equals()
, jika tidak semua taruhan dibatalkan.Jawaban:
Ada perbedaan mencolok di sini.
valueOf
mengembalikanInteger
objek, yang mungkin memiliki nilai-nilai di-cache antara -128 dan 127. Inilah sebabnya mengapa nilai pertama kembalitrue
- itu di-cache - dan nilai kedua kembalifalse
- 128 bukan nilai di-cache, sehingga Anda mendapatkan duaInteger
contoh terpisah .Penting untuk dicatat bahwa Anda membandingkan referensi dengan
Integer#valueOf
, dan jika Anda membandingkan nilai yang lebih besar dari yang didukung cache, itu tidak akan dievaluasitrue
, bahkan jika nilai yang diuraikan adalah setara (dalam kasus:)Integer.valueOf(128) == Integer.valueOf(128)
. Anda harus menggunakannyaequals()
sebagai gantinya.parseInt
mengembalikan primitifint
. Inilah sebabnya mengapa pengembalian nilai ketigatrue
-128 == 128
dievaluasi, dan tentu sajatrue
,.Sekarang, sedikit wajar terjadi untuk membuat hasil ketiga
true
:Konversi unboxing terjadi sehubungan dengan operator ekivalen yang Anda gunakan dan tipe data yang Anda miliki - yaitu,
int
danInteger
. Anda mendapatkanInteger
darivalueOf
di sisi kanan, tentu saja.Setelah konversi, Anda membandingkan dua
int
nilai primitif . Perbandingan terjadi persis seperti yang Anda harapkan sehubungan dengan primitif, jadi Anda akhirnya membandingkan128
dan128
.sumber
List
. Yang lainnya adalah primitif, yang hanya nilai mentah.==
. Lagi pula, sudah jelas sekarang.The
Integer
kelas memiliki cache statis, yang menyimpan 256 khususInteger
benda - satu untuk setiap nilai antara -128 dan 127. Dengan itu dalam pikiran, mempertimbangkan perbedaan antara ketiganya.Ini (jelas) membuat
Integer
objek baru .Ini mengembalikan
int
nilai primitif setelah parsing theString
.Ini lebih kompleks daripada yang lain. Ini dimulai dengan parsing the
String
. Kemudian, jika nilainya antara -128 dan 127, itu mengembalikan objek yang sesuai dari cache statis. Jika nilainya di luar kisaran ini, makanew Integer()
nilainya akan memanggil dan meneruskan nilainya, sehingga Anda mendapatkan objek baru.Sekarang, perhatikan tiga ungkapan dalam pertanyaan.
Ini mengembalikan true, karena
Integer
yang nilainya 127 diambil dua kali dari cache statis, dan dibandingkan dengan itu sendiri. Hanya ada satuInteger
objek yang terlibat, jadi ini kembalitrue
.Ini kembali
false
, karena 128 tidak ada dalam cache statis. Jadi yang baruInteger
dibuat untuk setiap sisi kesetaraan. Karena ada duaInteger
objek yang berbeda , dan==
untuk objek hanya kembalitrue
jika kedua sisi adalah objek yang sama persis, ini akan menjadifalse
.Ini membandingkan nilai primitif
int
128 di sebelah kiri, dengan objek yang baru dibuatInteger
di sebelah kanan. Tetapi karena tidak masuk akal untuk membandingkanint
denganInteger
, Java akan membuka kotak secara otomatisInteger
sebelum melakukan perbandingan; sehingga Anda akhirnya membandingkanint
denganint
. Karena primitif 128 sama dengan dirinya sendiri, ini kembalitrue
.sumber
Jaga pengembalian nilai dari metode ini. The valueOf metode mengembalikan sebuah contoh Integer:
The parseInt kembali metode bilangan bulat nilai (tipe primitif):
Penjelasan untuk perbandingan:
Dalam situasi Anda (sesuai dengan aturan di atas):
Ekspresi ini membandingkan referensi ke objek yang sama karena mengandung nilai Integer antara -128 dan 127 sehingga kembali
true
.Ungkapan ini membandingkan referensi ke objek yang berbeda karena mengandung nilai Integer yang tidak dalam <-128, 127> sehingga mengembalikan
false
.Ungkapan ini membandingkan nilai primitif (sisi kiri) dan referensi ke objek (sisi kanan) sehingga sisi kanan akan dibuka dan tipe primitifnya akan dibandingkan dengan kiri sehingga kembali
true
.sumber
==
, karena mereka adalah objek yang berbeda.Cache objek integer antara -128 dan 127 dari 256 Integer
Anda tidak harus membandingkan referensi objek dengan == atau ! = . Kamu harus menggunakan . sama dengan (..) sebagai gantinya, atau lebih baik - gunakan primitif int daripada Integer.
parseInt : Mem-parsing argumen string sebagai bilangan bulat desimal yang ditandatangani. Semua karakter dalam string harus berupa angka desimal, kecuali bahwa karakter pertama mungkin berupa tanda minus ASCII '-' ('\ u002D') untuk menunjukkan nilai negatif. Nilai integer yang dihasilkan dikembalikan, persis seperti jika argumen dan radix 10 diberikan sebagai argumen untuk metode parseInt (java.lang.String, int).
valueOf Mengembalikan objek Integer memegang nilai yang diekstraksi dari String yang ditentukan ketika diuraikan dengan radix yang diberikan oleh argumen kedua. Argumen pertama ditafsirkan sebagai mewakili integer yang ditandatangani di dalam radix yang ditentukan oleh argumen kedua, persis seperti jika argumen diberikan kepada metode parseInt (java.lang.String, int). Hasilnya adalah objek Integer yang mewakili nilai integer yang ditentukan oleh string.
setara dengan
radix - radix yang akan digunakan dalam menafsirkan s
jadi jika Anda sama
Integer.valueOf()
untuk peralihan integer-128 hingga 127 mengembalikan true dalam kondisi Anda
untuk
lesser than
-128 dangreater than
127 itu memberifalse
sumber
Untuk melengkapi jawaban yang diberikan, perhatikan juga hal-hal berikut:
Kode ini juga akan mencetak:
false
Sebagai pengguna Jay telah mengklaim dalam komentar untuk jawaban yang diterima, kehati-hatian harus diambil ketika menggunakan operator
==
pada objek, di sini Anda memeriksa apakah kedua referensi sama, yang tidak, karena mereka adalah objek yang berbeda, meskipun mereka mewakili sangat nilai yang sama. Untuk membandingkan objek, Anda harus menggunakanequals
metode ini:Ini akan mencetak:
true
Anda mungkin bertanya, Tapi mengapa baris pertama dicetak
true
? . Memeriksa kode sumber untukInteger.valueOf
metode ini, Anda dapat melihat yang berikut:Jika param adalah bilangan bulat antara
IntegerCache.low
(default ke -128) danIntegerCache.high
(dihitung pada saat runtime dengan nilai minimum 127) maka objek yang telah dialokasikan (cache) dikembalikan. Jadi ketika Anda menggunakan 127 sebagai parameter, Anda mendapatkan dua referensi ke objek cache yang sama dan mendapatkantrue
perbandingan referensi.sumber