8. Výrazy
Výraz se skládá z operandů a operátorů. Operandem může být konstanta,
proměnná, volání metody nebo opět výraz. Operátory udávají, co se má provést
s jednotlivými hodnotami operandů.
8.1. Aritmetické operátory
Všechny aritmetické operátory lze použít pro práci s celočíselnými
i racionálními hodnotami. V následující tabulce je uveden seznam
binárních aritmetických operátorů a jejich použití.
Oper. | Použití | Popis |
+ | op1 + op2 | součet operandů op1 a op2 |
- | op1 - op2 | rozdíl operandů op1 a op2 |
* | op1 * op2 | součin operandů op1 a op2 |
/ | op1 / op2 | podíl operandů op1 a op2 |
% | op1 % op2 | zbytek po dělení op1 operandem op2 |
|
Dále jsou k dispozici tyto unární aritmetické operátory:
Oper. | Použití | Popis |
+ | +op | indikace kladné hodnoty |
- | -op | aritmetická negace operandu |
++ | op++ | inkrementace op o 1 po jeho vyhodnocení |
++ | ++op | inkrementace op o 1 před jeho vyhodnocením |
--
|
op--
| dekrementace op o 1 po jeho vyhodnocení |
--
|
--op
| dekrementace op o 1 před jeho vyhodnocením |
|
8.2. Relační operátory
Relační operátory porovnávají dva výrazy ekvivalentních typů a
rozhodnou o platnosti vztahu mezi nimi. Výsledkem relačního operátoru je vždy
hodnota false nebo true .
Oper. | Použití | Výsledek je true jestliže |
> | op1 > op2 | op1 je větší než op2 |
>= | op1 >= op2 | op1 je větší než nebo roven op2 |
< | op1 < op2 | op1 je menší než op2 |
<= | op1 <= op2 | op1 je menší než nebo roven op2 |
== | op1 == op2 | op1 a op2 jsou si rovné |
!= | op1 != op2 | op1 a op2 si nejsou rovné |
|
Mezi relační operátory dále patří operátor instanceof , který porovnává,
zda objekt je instancí dané třídy nebo rozhraní. Jeho syntaxe je:
objekt instanceof JménoTřídyNeboRozhraní
Priklad 8.1. |
String retezec = "ahoj";
if (retezec instanceof String) // test na třídu
System.out.println("Je to String!");
if (retezec instanceof Runnable) // test na rozhraní
System.out.println("Implementuje Runnable!");
|
|
8.3. Logické operátory
Pro kombinaci relačních operátorů je nutné použít logické operátory. Například
výraz op1 < op2 < op3 je třeba zapsat jako logickou kombinaci dvou
relačních operátorů (op1 < op2) && (op2 < op3) . Java obsahuje tyto
logické operátory:
Oper. | Použití | Výsledek je true jestliže: |
&& | op1 && op2 | op1 a op2 nabývají hodnotu true |
|| | op1 || op2 | alespoň jeden z op je true |
! | !op | op nabývá hodnotu false (negace) |
|
8.4. Bitové operátory
Bitové operátory umožňují manipulaci s jednotlivými bity celočíselných
datových typů.
Oper. | Použití | Operace |
>> | op1 >> op2 | bitový posuv op1 doprava o op2 bitů |
<< | op1 << op2 | bitový posuv op1 doleva o op2 bitů |
>>> | op1 >>>op2 | jako >>, ale neznaménkově |
& | op1 & op2 | bitový AND |
| | op1 | op2 | bitový OR |
^ | op1 ^ op2 | bitový XOR |
˜ | ˜op | bitový doplněk |
|
8.5. Operátor přiřazení
Pro operátor přiřazení se používá znak "= ". Tento operátor lze
použít i pro inicializaci proměnných při deklaraci lokální proměnné (viz
9.4.).
Priklad 8.2. |
int slon = 2;
int chobot = 1;
String text1 = "Tri sloni maji tri choboty";
String text2;
chobot = slon = 3;
text2 = text1;
|
|
Při přiřazení hodnoty do referenční proměnné se objekt nebo pole
nekopíruje (1) , ale přiřadí se pouze reference.
Vlastní objekt nebo pole zůstává v paměti pouze v jednom exempláři.
Referenční proměnné lze přiřadit neplatnou referenci null.
Pro přiřazení lze použít některých zkrácených tvarů:
Oper. | Použití | Ekvivalent |
+= | op1 += op2 | op1 = op1 + op2 |
-= | op1 -= op2 | op1 = op1 - op2 |
*= | op1 *= op2 | op1 = op1 * op2 |
/= | op1 /= op2 | op1 = op1 / op2 |
%= | op1 %= op2 | op1 = op1 % op2 |
&= | op1 &= op2 | op1 = op1 & op2 |
|= | op1 |= op2 | op1 = op1 | op2 |
^= | op1 ^= op2 | op1 = op1 ^ op2 |
<<= | op1 <<= op2 | op1 = op1 << op2 |
>>= | op1 >>= op2 | op1 = op1 >> op2 |
>>>= | op1 >>>= op2 | op1 = op1 >>> op2 |
|
8.6. Operátor konverze (přetypování)
Konverze datových typů lze se rozdělit zhruba na tyto okruhy:
- identické konverze - konverze na tentýž typ (nepřetypovává se),
- rozšiřující konverze - provádějí se implicitně a není nutné uvádět
operátor přetypování,
- zužující konverze - při nich může dojít ke ztrátě informace a musí se
provádět operátorem přetypování - jeho syntaxe je:
( typ ) operand
- konverze základních datových typů na řetězec a opačně - viz
14.3.,
- zakázané konverze - konverze, které obvykle nemají smysl (například
konverze reference na double) a přetypování na void.
U příkazu přiřazení překladač automaticky provádí zužující konverze na typy
byte, short a char, pokud je na pravé straně výsledek výrazu
typu int a zároveň je výsledek v oboru hodnot těchto typů.
8.6.1. Rozšiřující konverze
Při provádění rozšiřující datové konverze nedochází ke ztrátě
informace. (2) Jedná
se o konverze, kde výsledný datový typ má větší obor hodnot než typ původní.
Při těchto konverzích nedojde k chybě za běhu programu. Zde je přehled
rozšiřujících konverzí pro základní datové typy:
- byte ---> short, int, long,
float, double,
- char, short ---> int, long, float, double,
- int ---> long, float, double,
- long ---> float, double,
- float ---> double.
Priklad 8.3. |
int big = 1234567890;
float approx = big; // ztráta informace
System.out.println(big - (int)approx); // vypíše číslo: -46
|
|
Mezi rozšiřující konverze pro referenční datové typy patří:
- třída S ---> třída T, kde S je potomek třídy
T,
- třída S ---> rozhraní K, kde S implementuje
rozhraní K,
- rozhraní J ---> rozhraní K, kde J je potomkem
rozhraní K,
- libovolné rozhraní nebo pole ---> třída Object (viz
11.5.),
- libovolné pole ---> rozhraní Cloneable(viz
11.5.),
- pole a[] ---> pole b[], kde a a b jsou
pole referenčních datových typů a konverze a ---> b je
rozšiřující.
Výsledkem rozšiřující konverze referenčních typů je pouze reference.
Neprovádí se žádná speciální akce s objektem nebo polem.
Kontrola správnosti konverze se provádí již při překladu a nemůže
vyvolat výjimku ClassCastException.
Priklad 8.4. |
Object x;
Double cislo = "Ahoj!";
x = text;
|
|
8.6.2. Zužující konverze
Při provádění zužující konverze může dojít ke ztrátě hodnoty a přesnosti. Zde
je jejich přehled pro základní datové typy:
- short ---> byte,
- short ---> byte, char,
- char ---> byte, short,
- int ---> byte, short, char
- long ---> byte, short, char, int
- float ---> byte, short, char,
int, long,
- double ---> byte, short, char,
int, long, float.
Zužující konverze mezi celočíselnými datovými typy se provede oříznutím
váhově vyšších bitů. Při konverzi z typu float nebo double na
celočíselný datový typ se provede nejdříve konverze na typ long
(popřípadě na int - při konverzi na int, short, char
nebo byte), a pak na cílový datový typ.
Priklad 8.5. |
System.out.println("255: " + (byte) 255); // Vypíše číslo: -1
|
|
Mezi zužující konverze pro referenční datové typy patří:
- třída S ---> třída T, kde S je rodičem třídy
T,
- třída S ---> rozhraní K, kde S není koncová
(final) a neimplementuje rozhraní K,
- rozhraní J ---> K, kde J je potomkem rozhraní
K,
- třída Object ---> libovolné rozhraní,
- třída Object ---> libovolné pole,
- rozhraní J ---> T, kde T není koncové,
- rozhraní J ---> třída T, kde T je koncová
a implementuje J,
- rozhraní J ---> rozhraní K, kde J
neimplementuje K a neexistuje metoda, kterou by obsahovala obě rozhraní
a která by zároveň měla různý návratový typ,
- pole a[] ---> pole b[], kde a a b jsou
pole referenčních datových typů a konverze a ---> b je
zužující.
Při konverzi může být vyvolána vyjímka ClassCastException.
8.7. Ternární operátor
Ternární operátor je jakousi obdobou příkazu if. Jeho syntaxe je:
výraz1 ? výraz2 : výraz3
Pokud výraz1 nabývá hodnoty true , vyhodnotí se
výraz2, v opačném případě se vyhodnotí výraz3.
Priklad 8.6. |
b != 0 ? c = a / b : c = 0; // pokud b je nenulové, provede se dělení
// jinak se do c přiřadí 0
|
|
8.8. Operátor new
Operátor new slouží k vytvoření objektu - syntaxe viz
11.1.1., 11.8..
8.9. Přehled priorit jednotlivých operátorů
Pokud zapsaný výraz obsahuje více operátorů, je vyhodnocování dáno jejich
prioritou. Dříve se vyhodnocují operátory s vyšší prioritou (ty s nižším
číslem). Operátory se stejnou prioritou se vyhodnocují zleva doprava. Pro
změnu pořadí vyhodnocování lze použít kulaté závorky.
P | Typ operátorů | Operátory |
1 | postfixové | [] . (parametry) op++
op- |
2 | unární operátory | ++op -op +op
-op ˜ ! |
3 | vytváření a přetyp. | new (typ) výraz |
4 | multiplikativní | * / % |
5 | aditivní | + - |
6 | posuvy | << >> >>> |
7 | relace | < > <= >= instanceof |
8 | ekvivalence | == != |
9 | bitové AND | & |
10 | bitové XOR | ^ |
11 | bitové OR | | |
12 | logické AND | && |
13 | logické OR | || |
14 | ternární | ? : |
15 | přiřazení | = += -= *= /= %= ^= &= |
| | |= <<= >>= >>>= |
|
Priklad 8.7. |
x = -(4 * (c + 2)); // změna pořadí vyhodnocování
|
|
|