98
Java 9 – Kompletní příručka jayzka
Alternativní řešení Při používání výše uvedených operátorů můžete počítat s tím, že v Javě (a s ní i ve většině ostatních programovacích jazyků) má, stejně jako v matematice, násobení a dělení přednost před sčítáním a odčítáním. Potřebujete-li proto nejprve dvě hodnoty sečíst, a teprve pak vynásobit, máte dvě možnosti: ● Sčítané hodnoty uzavřete do závorek a výsledný součet vynásobíte – např.: (3 + 4) * (5 + 6) ● Celou složitou operaci rozdělíte do několika kroků: int a = 3 + 4; int b = 5 + 6; int c = a * b; Většinou dáte přednost závorkám, u složitějších výrazů však bývá výhodnější (= přehlednější) rozdělit celý výpočet do několika kroků.
4.6
Možná to některé překvapí, ale výsledný program je v obou případech prakticky stejný. Podíváte-li se totiž do přeloženého programu, zjistíte, že nerozdělíte-li výpočet do několika kroků vy, udělá to za vás překladač. Dávejte proto vždy přednost takovému zápisu, který je pro vás přehlednější.
Operátor přetypování (typ)
Jsou okamžiky, kdy bychom potřebovali změnit typ nějakého výrazu. Někdy je to proto, že nám aktuální typ výrazu nevyhovuje, jindy je to proto, že víme něco, co překladač neví, a můžeme mu tímto způsobem napovědět (s takovýmito situacemi se brzy začneme setkávat).
Implicitní přetypování Mnohá přetypování za nás provede překladač automaticky – tato přetypování označujeme jako implicitní. Jiná musíme zadat sami – pak hovoříme o explicitním přetypování. Implicitně překladač přetypovává: ● U numerických primitivních datových typů z „menšího“ na „větší“. Přitom se řídí následujícím předpisem: char → ↓ byte → short → int → long → float → double→ Object 57G_Java 9 – Základy jazyka_ZLOM verze 1.00.7228 – 2017-10-31
Strana 98 z 558 Ukázka elektronické knihy, UID: KOS245820
Kapitola 4 Základní operátory
99
Šipky naznačují směr automatické implicitní konverze. Budu-li proto chtít uložit celé číslo do proměnné typu long nebo double, překladač za mne automaticky vloží potřebné přetypování. Kdybych to chtěl obráceně, musím zadat přetypování sám. První řádek předchozího „vzorečku“ naznačuje, že znaky (hodnoty typu char) se implicitně převádějí na celá čísla. Poslední šipka vpravo naznačuje, že libovolnou hodnotu primitivního typu je možno automaticky přetypovat na instanci třídy Object. V pozadí tohoto „přetypování“ se sice odehraje řada věcí, o kterých si povíme v druhé části, nicméně tento způsob „zobecnění“ uložené hodnoty možný je. ● U objektových typů se implicitně přetypovává ze specializovaného datového typu (z podtypu) na jeho obecnější podobu (na nadtyp). Jak už jsem několikrát naznačil, objektové programování staví na tvrzení, že všechno je objekt. Všechny objektové datové typy (tedy i třída String) jsou proto podtypy třídy Object a jejich instance jsou jen speciální případy instancí třídy Object. Instance libovolného objektového datového typu je proto překladač ochoten automaticky přetypovat na typ Object. Problematika podtypů a nadtypů je poněkud složitější. Budu se ji podrobněji věnovat až v druhé části věnované objektovému programování.
Příklady implicitního přetypování Několik příkladů implicitního přetypování najdete ve výpisu 4.5. Budeme v nich využívat některé z proměnných definovaných v minulé kapitole a pojmenovaných podle svých datových typů. V zájmu úspory místa ukazují příklady jenom některé z možností. Předpokládám, že zájemci si dokáží zbylé možnosti ověřit sami. Pojďme si je nyní projít. Na řádku 1 ukazuji, že hodnotu typu char mohu bez problému uložit do proměnné typu int. Stejně tak i hodnotu typu short (řádek 5). Je to proto, že hodnotu „menšího“ typu ukládám do proměnné „většího“ typu. Jak se ale můžete přesvědčit z reakce na příkaz na řádku 9, obráceně to možno není. Je přitom jedno, že přiřazuji nulu, která se do proměnné typu short bez problému vejde. Hodnotu „většího“ typu prostě do proměnné „menšího“ typu přiřadit nejde. Překladač by musel uplatnit ztrátovou konverzi, při které by mohly být odebrány některé číslice, a to si sám nikdy nedovolí; jenom na vaše výslovné přání. Jedinou výjimkou je přiřazení hodnoty nějakého literálu, protože jejich hodnotu překladač zná. Může si zkontrolovat, že se do cílové proměnné opravdu vejde a je si hlavně jistý, že se tato hodnota po spuštění programu nezmění. Přiřazení nejvyšší možné hodnoty typu byte do proměnné tohoto typu se na řádku 15 povedlo. Na řádku 19 při pokusu o přiřazení hodnoty jen o jedničku 57G_Java 9 – Základy jazyka_ZLOM verze 1.00.7228 – 2017-10-31
Strana 99 z 558 Ukázka elektronické knihy, UID: KOS245820
100
Java 9 – Kompletní příručka jayzka
větší již překladač poznal, že tato hodnota se do proměnné nevejde a oprávněně se vzbouřil. Výpis 4.5:
Implicitní přetypování a jeho možnosti
1 jshell> _int = _char; //Znak lze převést na int, long, float a double => projde 2 _int ==> 0 3 | assigned to _int : int 4 5 jshell> _int = _short; //Převádí se z menšího na větší => projde 6 _int ==> 0 7 | assigned to _int : int 8 9 jshell> _short = _int; //Z „většího“ na „menší“ implicitně převádět nelze 10 | Error: 11 | incompatible types: possible lossy conversion from int to short 12 | _short = _int; //Z většího na menší implicitně převádět nelze 13 | ^--^ 14 15 jshell> _byte = 127; //„Vhodně velký“ literál je možno přiřadit i menším typům 16 _byte ==> 127 17 | assigned to _byte : byte 18 19 jshell> _byte = 128; //Hodnota větší než přípustná způsobí chybu 20 | Error: 21 | incompatible types: possible lossy conversion from int to byte 22 | _byte = 128; //Hodnota větší než přípustná způsobí chybu 23 | ^-^ 24 25 jshell> _Object = _byte; //Hodnoty primitivních typů lze konvertovat na objekty 26 _Object ==> 127 27 | assigned to _Object : Object 28 29 jshell> _Object = _String; //Převádí se z podtypu na nadtyp => projde 30 _Object ==> "i=100, j=130, k=80" 31 | assigned to _Object : Object 32 33 jshell> _String = _Object; //Z obecnějšího na speciální implicitně převádět nelze 34 | Error: 35 | incompatible types: java.lang.Object cannot be converted to java.lang.String 36 | _String = _Object; //Z obecnějšího na speciální implicitně převádět nelze 37 | ^-----^ 38 39 jshell> Na řádku 25 se můžete přesvědčit, že překladač je ochoten konvertovat hodnotu typu byte na objekt, tj. vytvořit objekt, do nějž danou hodnotu zabalí a který ji bude poté reprezentovat mezi objekty. 57G_Java 9 – Základy jazyka_ZLOM verze 1.00.7228 – 2017-10-31
Strana 100 z 558 Ukázka elektronické knihy, UID: KOS245820