Kodėl Java + =, - =, * =, / = priskyrimo operatoriaus priskyrimai nereikalauja?

Iki šiol maniau, pavyzdžiui:

 i += j; 

Buvo tik etiketė:

 i = i + j; 

Bet jei bandysime tai:

 int i = 5; long j = 8; 

Tada i = я + j; nebus sukompiliuoti, bet i += j; sukurs baudą.

Ar tai reiškia, kad i += j; yra kažką panašaus ženklo i = (type of i) (i + j) ?

3326
03 янв. „ Honza Brabec“ nustatė sausio 03 d 2012-01-03 13:10 '12 13:10 2012-01-03 13:10
@ 11 atsakymų

Kaip visada su šiais klausimais, JLS turi atsakymą. Šiuo atveju §15.26.2 Ryšio priskyrimo ataskaitos . Poveikis:

Kumuliacinė išraiška E1 op= E2 lygi E1 = (T)((E1) op (E2)) , kur T yra E1 tipas, išskyrus tai, kad E1 yra vertinamas tik vieną kartą.

Pavyzdys pateiktas 15.26.2 punkte

[...] teisingas kodas:

 short x = 3; x += 4.6; 

ir sukelia x vertę 7, nes ji atitinka:

 short x = 3; x = (short)(x + 4.6); 

Kitaip tariant, jūsų spėjimas yra teisus.

2241
03 янв. Atsakymą pateikė Lukas Ederis sausio 03 d 2012-01-03 13:15 '12, 13:15, 2012-01-03 13:15

Geras šio pavyzdžio pavyzdys yra * = arba / =

 byte b = 10; b *= 5.7; System.out.println(b); // prints 57 

arba

 byte b = 100; b /= 2.5; System.out.println(b); // prints 40 
border=0

arba

 char ch = '0'; ch *= 1.1; System.out.println(ch); // prints '4' 

arba

 char ch = 'A'; ch *= 1.5; System.out.println(ch); // prints 'a' 
450
03 янв. Atsakymas, kurį pateikė Peter Lawrey Jan 03 2012-01-03 13:20 '12, 13:20, 2012-01-03 13:20

Labai geras klausimas. „Java“ kalbos specifikacija patvirtina jūsų pasiūlymą.

Pavyzdžiui, šis kodas yra teisingas:

 short x = 3; x += 4.6; 

ir sukelia x vertę 7, nes ji atitinka:

 short x = 3; x = (short)(x + 4.6); 
231
03 янв. atsakymą pateikė Thirler sausio 03 2012-01-03 13:17 '12 13:17 2012-01-03 13:17

Taip,

dažniausiai rašydami

 i += l; 

kompiliatorius konvertuoja šią vertę į

 i = (int)(i + l); 

Aš tiesiog patikrinau .class failo kodą.

Tikrai gerai žinoti

169
03 янв. atsakymas duotas Umesh Awasthi 03 jan. 2012-01-03 13:19 '12 13:19 2012-01-03 13:19

jums reikia daryti nuo long iki int explicitly , jei yra i = i + l , tada jis surinks ir duos teisingą rezultatą. kaip

 i = i + (int)l; 

arba

 i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly. 

bet += tai veikia gerai, nes operatorius netiesiogiai atlieka tipo liejimą iš dešiniojo kintamojo tipo į kairiojo kintamojo tipą, todėl nereikia aiškiai nurodyti.

86
03 янв. atsakymas pateikiamas dku.rajkumar 03 jan. 2012-01-03 13:15 '12, 13:15, 2012-01-03 13:15

Problema čia yra liejimas.

Pridėjus int ir ilgą laiką,

  • Int objektas yra saugomas ilgai ir abu yra pridedami, ir jūs gaunate ilgą objektą.
  • tačiau ilgas objektas negali būti netiesiogiai perduotas int. Taigi jūs turite tai padaryti aiškiai.

Bet += užkoduotas tokiu būdu, kad jis tipo. i=(int)(i+m)

57
03 янв. Atsakymą pateikė Dinesh Sachdev 108 03 jan. 2012-01-03 13:20 '12, 13:20, 2012-01-03 13:20

„Java“ tipo konversijose tai atliekama automatiškai, kai išraiška dešinėje užduoties operacijos pusėje gali būti saugiai perkelta į kintamojo tipą kairėje darbo pusėje. Taigi, mes galime saugiai priskirti:

  baitas -> trumpas -> int -> ilgas -> plaukimas -> dvigubas. 

Tas pats neveiks atvirkščiai. Pavyzdžiui, mes negalime automatiškai konvertuoti ilgai į int, nes pirmasis reikalauja daugiau atminties nei pastaroji, todėl informacija gali būti prarasta. Norėdami priversti tokį transformavimą, privalome atlikti aiškią konversiją.
Tipas - konversija

48
23 янв. Atsakymas pateikiamas tinker_fairy sausio 23 d 2013-01-23 08:50 '13, 8:50, 2013-01-23 08:50

Kartais šį klausimą galima užduoti pokalbio metu.

Pavyzdžiui, kai rašote:

 int a = 2; long b = 3; a = a + b; 

Nėra automatinio tipo keitimo. „C + +“ pirmiau minėto kodo kompiliavimo klaida nebus, tačiau „Java“ gausite panašų į Incompatible type exception .

Norėdami to išvengti, turėtumėte parašyti tokį kodą:

 int a = 2; long b = 3; a += b;// No compilation error or any exception due to the auto typecasting 
38
02 дек. Atsakymas, kurį pateikė Stopfan 02 Dec. 2014-12-02 13:40 '14, 13:40 2014-12-02 13:40

Pagrindinis skirtumas yra tas, kad su a = a + b nėra tipo konvertavimo, todėl kompiliatorius yra piktas su jumis neužrašant. Bet su a += b , tai, ką jis iš tikrųjų daro, yra b tipo liejimas į tipą, suderinamą su a . Taigi, jei tai darote

 int a=5; long b=10; a+=b; System.out.println(a); 

Ką jūs iš tikrųjų darote:

 int a=5; long b=10; a=a+(int)b; System.out.println(a); 
19
08 июня '15 в 2:27 2015-06-08 02:27 atsakymas pateikiamas takra birželio 15 d., 15 val. 2:27 2015-06-08 02:27

Plonas taškas čia ...

i+j yra numanomas i+j , kai j yra dvigubas ir i yra int. „Java“ ALWAYS konvertuoja sveikąjį skaičių į dvigubą, kai atlieka operaciją tarp jų.

Norėdami išaiškinti i+=j kur i yra sveikasis skaičius ir j yra dvigubas, galima apibūdinti kaip

 i = <int>(<double>i + j) 

Žr. Šį netiesioginio liejimo aprašymą.

Tokiu atveju, norint aiškumo, jums gali tekti įdėti j į (int) .

8
18 янв. Gabe Nones atsakymas, sausio 18 d 2016-01-18 23:07 '16 at 11:07 PM 2016-01-18 23:07

Priskyrimo operatoriaus atveju atliekamas automatinis vidinio tipo paleidimas:

 byte b1 = 10; //b1 = b1 + 1; Compile time error because found int System.out.println(b1); byte b3 = 10; b3 += 1; //in compound assignment implicit type casting will be performed simultaneously System.out.println("b3=: "+b3); byte b4 = 127; b4 += 3; //in compound assignment implicit type casting will be performed simultaneously System.out.println("b4=: "+b4);//-126 

Kai kuriais atvejais prarasite tam tikrą vertę:

 int i = 1; i += 1.5; System.out.println("i=: "+i); //will print 2, and you lost .5 !!! 
-3
04 июня '17 в 11:03 2017-06-04 11:03 atsakymą pateikė „ Suganthan Madhavan Pillai“ birželio 4 d. 17 d. 11:03 2017-06-04 11:03