Sampai hari ini, saya pikir itu misalnya:
i += j;
Hanya sebuah jalan pintas untuk:
i = i + j;
Tapi jika kita coba ini:
int i = 5;
long j = 8;
Maka i = i + j;
tidak akan mengkompilasi tapi i += j;
akan mengkompilasi baik-baik saja.
Apakah ini berarti bahwa pada kenyataannya i += j;
jalan pintas untuk sesuatu seperti ini
aku = (tipe i) (i + j)
?
Seperti biasa dengan pertanyaan-pertanyaan ini, JLS memegang jawaban. Dalam hal ini §15.26.2 Compound Assignment Operator. Ekstrak:
senyawa penugasan ekspresi dari bentuk
E1 op= E2
setara denganE1 = (T)((E1) &op amp;nbsp;(E2))
, di manaT
adalah jenisE1
, kecuali bahwaE1
adalah dievaluasi hanya sekali.
Contoh yang dikutip dari §15.26.2
[...] kode berikut ini benar:
pendek x = 3; x += 4.6;
dan hasil x memiliki nilai 7 karena itu adalah setara dengan:
pendek x = 3; x = (short)(x + 4.6);
Dengan kata lain, asumsi anda adalah benar.
Sebuah contoh yang baik dari pengecoran ini menggunakan *= atau /=
byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57
atau
byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40
atau
char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'
atau
char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'
Pertanyaan yang sangat bagus. The Bahasa Jawa spesifikasi menegaskan saran anda.
sebagai contoh, kode berikut ini benar:
pendek x = 3; x += 4.6;
dan hasil x memiliki nilai 7 karena itu adalah setara dengan:
pendek x = 3; x = (short)(x + 4.6);
Ya,
pada dasarnya ketika kita menulis
i += l;
compiler mengubah ini untuk
i = (int)(i + l);
Aku hanya memeriksa .kelas
file kode.
Benar-benar hal yang baik untuk tahu
yang anda butuhkan untuk melemparkan dari lama
untuk int
eksplisit
dalam kasus i = i + l
maka akan mengkompilasi dan memberikan output yang benar. seperti
i = i + (int)l;
atau
i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.
tapi dalam kasus +=
ini hanya bekerja dengan baik karena operator secara implisit melakukan type casting dari tipe kanan variabel jenis dari kiri variabel sehingga tidak perlu melemparkan secara eksplisit.
Masalahnya di sini melibatkan tipe casting.
Ketika anda menambahkan int dan panjang,
Tapi +=
dikodekan sedemikian rupa sehingga tidak jenis pengecoran. i=(int)(i+m)
Di Jawa jenis konversi dilakukan secara otomatis ketika jenis ekspresi pada sisi kanan dari tugas operasi dapat dengan aman dipromosikan ke tipe dari variabel di sisi kiri dari tugas. Dengan demikian kita dapat menetapkan:
byte -> pendek -> int -> panjang -> float -> ganda.Hal yang sama tidak akan bekerja sebaliknya. Misalnya kita tidak bisa secara otomatis mengkonversi panjang ke int karena yang pertama memerlukan penyimpanan yang lebih besar dari yang kedua dan akibatnya informasi yang mungkin akan hilang. Untuk memaksa konversi tersebut kita harus melakukan konversi eksplisit. [Jenis - Konversi][1]
Kadang-kadang, pertanyaan seperti itu dapat ditanyakan pada saat wawancara.
Misalnya, ketika anda menulis:
int a = 2;
long b = 3;
a = a + b;
tidak ada otomatis typecasting. Dalam C++ tidak akan ada kesalahan kompilasi kode di atas, tapi di Jawa, anda akan mendapatkan sesuatu seperti tidak Kompatibel jenis pengecualian
.
Jadi untuk menghindari hal itu, anda harus menulis kode seperti ini:
int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting
Perbedaan utama adalah bahwa dengan a = a + b
, tidak ada typecasting terjadi, dan jadi compiler akan marah pada anda untuk tidak typecasting. Tapi dengan a += b
, apa itu's benar-benar lakukan adalah typecasting b
untuk jenis kompatibel dengan a
. Jadi, jika anda melakukan
int a=5;
long b=10;
a+=b;
System.out.println(a);
Apa yang anda're benar-benar lakukan adalah:
int a=5;
long b=10;
a=a+(int)b;
System.out.println(a);
Titik halus di sini...
Ada implisit typecast untuk i+j
ketika j
adalah ganda dan aku
adalah int.
Jawa SELALU mengkonversi bilangan bulat ke ganda bila ada operasi antara mereka.
Untuk memperjelas i+=j
di mana aku
adalah bilangan bulat dan j
adalah ganda dapat digambarkan sebagai
i = <int>(<double>i + j)
Lihat: ini keterangan dari casting implisit
Anda mungkin ingin untuk typecast j
untuk (int)
dalam hal ini untuk kejelasan.
Bahasa jawa-Spesifikasi mendefinisikan E1 op= E2
untuk menjadi setara dengan E1 = (T) ((E1) op (E2))
di mana T
adalah jenis E1
dan E1
adalah dievaluasi sekali.
Yang's jawaban teknis, tapi anda mungkin bertanya-tanya mengapa itu's sebuah kasus. Nah, let's mempertimbangkan program berikut.
public class PlusEquals {
public static void main(String[] args) {
byte a = 1;
byte b = 2;
a = a + b;
System.out.println(a);
}
}
Apa ini program cetak?
Apa kau kira 3? Terlalu buruk, program ini tidak't kompilasi. Mengapa? Nah, begitu terjadi bahwa penambahan byte di Jawa didefinisikan untuk kembali sebuah int
. Ini, aku percaya itu karena Mesin Virtual Java doesn't define byte operasi untuk menghemat bytecodes (tidak terbatas jumlah mereka, setelah semua), menggunakan bilangan bulat operasi bukan merupakan implementasi detail terkena dalam bahasa.
Tapi jika a = a + b
doesn't bekerja, yang berarti a += b
tidak akan pernah bekerja untuk byte jika E1= E2
didefinisikan sebagai E1 = E1 + E2
. Sebagai contoh sebelumnya menunjukkan, bahwa akan benar-benar terjadi. Sebagai hack untuk membuat +=
operator bekerja untuk byte dan celana pendek, ada yang implisit cast yang terlibat. It's tidak yang besar dari hack, tapi kembali pada Java 1.0 bekerja, fokus pada mendapatkan bahasa dirilis untuk mulai dengan. Sekarang, karena kompatibilitas mundur, hack ini diperkenalkan di Jawa 1.0 tidak't akan dihapus.