a += b vs a = a + b v Javě
Často se setkávám s tvrzením, že v Javě přiřazení a += b je to samé jako a = a + b. Také si to myslíte? Ano? Jste si tím skutečně jisti?
Pokud jste si tím opravdu tak jisti, jak byste vysvětlili následující věc? Mějme jednoduchý kousek kódu
1 2 3 4 5 6 7 8 9 | // CompoundAssignmentTest.java class CompoundAssignmentTest { public static void main(String[] args) { int a = 1; float b = 2.0f; a += b; a = a + b; } } |
a zkusme ho zkompilovat.
> javac -version javac 1.6.0_03 > javac CompoundAssignmentTest.java CompoundAssignmentTest.java:7: possible loss of precision found : float required: int a = a + b; ^ 1 error
Hmm. Nejde. Podíváme-li se pozorně, vidíme, že chyba nastala až na řádce 7, tedy na řádce obsahující kód a = a + b;. Zakomentujeme-li řádek 7 a zkusíme kód zkompilovat znovu, vše je úspěšně zkompilováno. Pokud jsou přiřazení a += b a a = a + b stejná, jak je možné, že složené přiřazení a += b jde zkompilovat a přiřazení a = a + b nejde?
Odpověď je celkem jednoduchá. Podívejme se do The Java Language Specification, 3rd Edition. První odstavec kapitoli 15.26.2 Compound Assignment Operators říká:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
Aha! Implicitní přetypování! Naše řádka 6 a += b; je tedy převedena na a = (int)(a + b);. Na řádce 7 a = a + b; implicitní koverze na int není. Proto jsme dostali chybu při kompilaci. Na tuto vlastnost složeného přiřazení bychom si měli dávat pozor. V našem případě je proměnná a typu int a proměnná b typu float. Při vyhodnocování výrazu (a + b) je hodnota proměnné a povýšena na typ float a je sečtena s hodnotou proměnné b. Výsledná hodnota je typu float. Až sem je vše v pořádku. Nyní však dojde k implicitní konverzi hodnoty typu float na typ int a její následné přiřazení do proměnné a. Této konverzi se říká Narrowing Primitive Conversion a může při ní dojít ke ztrátě dat. Tuto implicitní konverzi u složeného přiřazení za nás udělal kompilátor tím, že vygeneroval odpovídající instrukce Java bajt kódu.
Pořád si myslíte, že a += b a a = a + b je v Javě to samé?
Komentáře
Komentář od Ladislav Thon
Datum: 17. 1. 2008, 12:40
Ech, takových záludností v Javě je, doporučuju knížku http://www.javapuzzlers.com/
Komentář od trk
Datum: 20. 1. 2008, 14:09
Mne to teda jako zaludnost nepripada. Jenze ja mam tu vyhodu, ze jsem se Javu neucil na stredni/vysoke skole scitanim matic, ale poradne


Komentář od ufak
Datum: 17. 1. 2008, 12:04
To teda neni hezke. Mel by dat take warning.
Dobry postreh!