Sampai hari ini, saya pikir itu misalnya:
i += j;
Itu hanya jalan pintas untuk:
i = i + j;
Tetapi jika kita coba ini:
int i = 5;
long j = 8;
Maka i = i + j;
tidak akan dikompilasi tetapi i += j;
akan dikompilasi dengan baik.
Apakah ini berarti bahwa sebenarnya i += j;
merupakan jalan pintas untuk hal seperti ini
i = (type of i) (i + j)
?
java
casting
operators
variable-assignment
assignment-operator
Honza Brabec
sumber
sumber
i+=(long)j;
bahkan akan dikompilasi dengan baik.i += (int) f;
melakukan f sebelum penambahan, jadi itu tidak setara.(int) i += f;
melemparkan hasil setelah penugasan, tidak sama. tidak akan ada tempat untuk memasang pemain yang menandakan bahwa Anda ingin memberikan nilai setelah menambahkan, tetapi sebelum penugasan.Jawaban:
Seperti biasa dengan pertanyaan-pertanyaan ini, JLS memegang jawabannya. Dalam hal ini §15.26.2 Operator Penugasan Majemuk . Ekstrak:
Contoh yang dikutip dari §15.26.2
Dengan kata lain, asumsi Anda benar.
sumber
i+=j
kompilasi ketika saya memeriksa diri saya sendiri, tetapi itu akan mengakibatkan hilangnya presisi bukan? Jika itu masalahnya, mengapa itu tidak memungkinkan terjadi di i = i + j juga? Mengapa mengganggu kami di sana?i += j
), lebih aman untuk mengasumsikan bahwa kehilangan presisi diinginkan dibandingkan dengan kasus lainnya (i = i + j
)E1 op= E2 is equivalent to E1 = (T)((E1) op (E2))
,, jadi itu semacam typecasting tersirat seperti (turun dari panjang ke int). Sedangkan di i = i + j, kita harus melakukannya secara eksplisit, yaitu, menyediakan(T)
bagian dalamE1 = ((E1) op (E2))
bukan?Contoh yang baik dari casting ini menggunakan * = atau / =
atau
atau
atau
sumber
A
;)ch += 32
= DPertanyaan yang sangat bagus The Java Bahasa spesifikasi menegaskan saran Anda.
sumber
double->float
sebagai pelebaran, atas dasar bahwa nilai-nilai tipefloat
mengidentifikasi bilangan real kurang spesifik daripada yang bertipedouble
. Jika seseorang memandangdouble
sebagai alamat pos yang lengkap danfloat
sebagai kode pos 5 digit, dimungkinkan untuk memenuhi permintaan untuk kode pos yang diberikan alamat lengkap, tetapi tidak mungkin untuk secara akurat menentukan permintaan untuk alamat lengkap yang hanya diberikan kode pos . Mengonversi alamat jalan ke kode pos adalah operasi yang merugi, tapi ...float->double
sama dengan mengkonversi kode pos AS 90210 dengan "Kantor Pos AS, Beverly Hills CA 90210".Iya,
pada dasarnya ketika kita menulis
kompiler mengonversi ini menjadi
Saya baru saja memeriksa
.class
kode file.Benar-benar hal yang baik untuk diketahui
sumber
Anda perlu melakukan cast dari
long
keint
explicitly
dalam kasusi = i + l
maka akan mengkompilasi dan memberikan output yang benar. Sukaatau
tetapi dalam kasus
+=
itu hanya berfungsi dengan baik karena operator secara implisit melakukan pengecoran tipe dari jenis variabel kanan ke jenis variabel kiri sehingga tidak perlu dilemparkan secara eksplisit.sumber
int
dilakukan setelah para+
. Compiler akan (harus?) Memberikan peringatan jika ia benar-benar melemparkanlong
keint
.Masalahnya di sini adalah tipe casting.
Saat Anda menambahkan int dan panjang,
Tetapi
+=
dikodekan sedemikian rupa sehingga tidak mengetik casting.i=(int)(i+m)
sumber
Di Java, konversi jenis dilakukan secara otomatis ketika jenis ekspresi di sisi kanan operasi penugasan dapat dipromosikan dengan aman ke jenis variabel di sisi kiri penugasan. Dengan demikian kami dapat menetapkan:
Hal yang sama tidak akan bekerja sebaliknya. Sebagai contoh, kita tidak dapat secara otomatis mengkonversi panjang ke int karena yang pertama membutuhkan lebih banyak penyimpanan daripada yang kedua dan akibatnya informasi mungkin hilang. Untuk memaksa konversi semacam itu, kita harus melakukan konversi eksplisit.
Jenis - Konversi
sumber
long
2 kali lebih besar darifloat
.float
tidak dapat menampung setiapint
nilai yang mungkin , dan adouble
tidak dapat menyimpan setiaplong
nilai yang mungkin .double d=33333333+1.0f;
tanpa keluhan, meskipun hasilnya 33333332.0 kemungkinan tidak akan seperti yang dimaksudkan (kebetulan, jawaban 33333334.0f yang benar secara hitung akan diwakili sebagai salah satufloat
atauint
).Terkadang, pertanyaan seperti itu bisa ditanyakan pada wawancara.
Misalnya, ketika Anda menulis:
tidak ada typecasting otomatis. Dalam C ++ tidak akan ada kesalahan saat mengkompilasi kode di atas, tetapi di Jawa Anda akan mendapatkan sesuatu seperti
Incompatible type exception
.Jadi untuk menghindarinya, Anda harus menulis kode Anda seperti ini:
sumber
op
penggunaan di C ++ dengan penggunaannya di Jawa. Saya selalu suka melihat hal-hal sepele ini dan saya pikir mereka menyumbangkan sesuatu untuk percakapan yang mungkin sering diabaikan.Perbedaan utama adalah bahwa dengan
a = a + b
, tidak ada typecasting yang sedang berlangsung, sehingga kompiler marah kepada Anda karena tidak typecasting. Tapi dengana += b
, apa yang sebenarnya dilakukannya adalah typecastingb
ke tipe yang kompatibel dengannyaa
. Jadi, jika Anda melakukannyaApa yang sebenarnya Anda lakukan adalah:
sumber
Titik halus di sini ...
Ada typecast implisit untuk
i+j
kapanj
ganda dani
int. Java SELALU mengubah integer menjadi dobel ketika ada operasi di antara mereka.Untuk memperjelas di
i+=j
manai
bilangan bulat danj
ganda dapat digambarkan sebagaiLihat: deskripsi tentang casting implisit ini
Anda mungkin ingin typecast
j
ke(int)
dalam hal ini untuk kejelasan.sumber
int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;
. Menambahkan nolsomeInt
tidak seharusnya memengaruhi nilainya, tetapi mempromosikansomeInt
kefloat
dapat mengubah nilainya.Spesifikasi Bahasa Jawa mendefinisikan
E1 op= E2
setara dengan diE1 = (T) ((E1) op (E2))
manaT
adalah jenisE1
danE1
dievaluasi sekali .Itu jawaban teknis, tetapi Anda mungkin bertanya-tanya mengapa itu sebuah kasus. Nah, mari kita simak program berikut ini.
Apa yang dicetak oleh program ini?
Apakah Anda menebak 3? Sayang sekali, program ini tidak dapat dikompilasi. Mengapa? Nah, kebetulan bahwa penambahan byte di Jawa didefinisikan untuk mengembalikan sebuah
int
. Ini, saya percaya itu karena Java Virtual Machine tidak mendefinisikan operasi byte untuk menghemat bytecodes (bagaimanapun, ada sejumlah yang terbatas), menggunakan operasi integer sebagai gantinya adalah detail implementasi yang diekspos dalam bahasa.Tetapi jika
a = a + b
tidak bekerja, itu berartia += b
tidak akan pernah bekerja untuk byte jika ituE1 += E2
didefinisikanE1 = E1 + E2
. Seperti yang ditunjukkan contoh sebelumnya, itu memang benar. Sebagai peretasan untuk membuat+=
operator bekerja untuk byte dan celana pendek, ada pemeran yang terlibat. Ini bukan retasan yang hebat, tetapi pada saat Java 1.0 bekerja, fokusnya adalah pada pelepasan bahasa untuk memulai. Sekarang, karena kompatibilitas ke belakang, peretasan ini diperkenalkan di Java 1.0 tidak dapat dihapus.sumber