Operátor

  • "Znaménko operace", pokyn pro vykonání operace při vyhodnocení výrazu.

  • V Javě mají operátory napevno daný význam, nelze je přetěžovat jako v C++.

  • Operátor dle počtu parametrů (argumentů) bývá

    • unární (např. minus),

    • binární (např. děleno) nebo

    • ternární (podmíněný výraz).

  • Každý operátor má určen typ svých argumentů nebo

  • může být polymorfní, aplikovatelný na různé typy.

Výraz

  • Syntakticky správný řetězec operandů a operátorů s případnými závorkami

  • Operandy jsou:

    • literály (přímo zadané hodnoty, třeba 1.23),

    • proměnné nebo

    • funkční volání.

  • Výraz lze při splnění dalších podmínek vyhodnotit (spočítat) a získat výsledek.

Aritmetické

  • Binární (dvouparametrové) aritmetické operátory: + - * / % (zbytek po celočíselném dělení)

  • Operátor dělení / je polymorfní

    • funguje pro celočíselné argumenty (byte, short, int a long) jako celočíselný

    • pro floating-point (float, double) jako obyčejné dělení.

  • Na to je třeba dávat pozor — i když dvě (fakticky i typově) celá čísla nejsou dělitelná, jako podíl se nám vrátí vždy celé číslo (typově i hodnotově).

  • Abychom dosáhli desetinného výsledku, musí být aspoň jeden z operandů typově s pohyblivou řádovou čárkou.

  • Lze zařídit např. typovou konverzí ((double)a)/b pro celočíselné proměnné a, b

  • nebo použitím literálu neceločíselného typu, např. double d = 1.0/i

Logické

  • Pracují nad logickými (booleovskými) hodnotami,

  • vč. výsledků relačních operací (porovnávání) <, >, == , apod.

Logické — součiny

Logické součiny (AND)
  • & nepodmíněný součin, vždy se vyhodnotí oba operandy,

  • && podmíněný součin, líné vyhodnocování (lazy evaluation) — druhý operand se vyhodnotí, jen nelze-li o výsledku součinu rozhodnout z hodnoty prvního

Logické — součty, negace

Logické součty (OR)
  • | nepodmíněný součet, vždy se vyhodnotí oba operandy,

  • || podmíněný součet, líné vyhodnocování — druhý operand se vyhodnotí, jen nelze-li o výsledku rozhodnout z hodnoty prvního

Negace (NOT)
  • ! vrátí znegovanou logickou hodnotu argumentu

Relační (porovnávací)

Uspořádání

<, , >=, > lze použít na porovnávání primitivních číselných a znakových hodnot

Rovnost

==, != test na rovnost/nerovnost lze navíc použít na porovnávání primitivních hodnot i objektů

Porovnávání objektů

  • Pozor na porovnávání objektů.

  • Operátor == vrací true jen při rovnosti odkazů, tj. jsou-li objekty identické.

  • Rovnost obsahu (tedy "rovnocennost") objektů se zjišťuje voláním metody o1.equals(o2).

  • equals se může podívat "dovnitř" objektů, je-li tak napsaná.

  • Aby to takto fungovalo, musíme ji my sami u našich vlastních typů překrýt (=sami napsat).

  • Blíže viz Porovnávání objektů

Porovnávání floating-point čísel

  • Pozor na srovnávání floating-point čísel na rovnost.

  • Je třeba počítat s chybami zaokrouhlení.

  • Místo porovnání na přesnou rovnost raději používejme jistou toleranci.

  • abs(expected-actual) < delta

Bitové operace

  • bitový součin &

  • bitový součet |

  • bitový exkluzivní součet (XOR) (znak "stříška") ^

  • bitová negace (bitwise-NOT) (znak "tilda") ~ obrátí bity argumentu a výsledek vrátí

Bitové posuny

  • vlevo << o stanovený počet bitů

  • vpravo >> o stanovený počet bitů s respektováním znaménka

  • vpravo >>> o stanovený počet bitů bez respektování znaménka

Operátor podmíněného výrazu ? :

Formát: booleovskýVýraz ? hodnotaKdyžPlatí : hodnotaKdyžNeplatí

Příklad: x < 0 ? 0 : x (vrátí x pokud je nezáporné, jinak 0)

  • Jediný ternární operátor v Javě, navíc polymorfní.

  • Pracuje nad různými typy 2. a 3. argumentu.

  • Platí-li první operand (má hodnotu true),

    • je výsledkem hodnota druhého operandu

    • jinak je výsledkem hodnota třetího operandu

  • Typ prvního operandu musí být boolean, typy druhého a třetího musí být přiřaditelné do výsledku.

Operátory typové konverze (přetypování)

  • Píše se (typ)hodnota , např. (Person)o, kde o byla proměnná deklarovaná jako Object.

  • Pro objektové typy se ve skutečnosti nejedná o žádnou konverzi spojenou se změnou obsahu objektu, nýbrž pouze o potvrzení (běhovou typovou kontrolu), že běhový typ objektu je ten požadovaný — např. (viz výše) že o je typu Person.

  • Naproti tomu u primitivních typů se jedná o skutečný převod, tzn. úpravu hodnoty — např. int přetypujeme na short a ořeže se tím rozsah.

Operátor zřetězení +

  • Plus je rovněž polymorfním operátorem.

  • Chová se jinak pro čísla — sčítá a jinak pro řetězce, kde spojuje.

  • Výsledkem je vždy řetězec, ale argumenty mohou být i jiných typů,

    int i = 1;
    System.out.println("variable i = " + i);
  • Tento kód je v pořádku, s řetězcovou konstantou se spojí řetězcová podoba dalších argumentů (např. čísla).

  • Pokud je argumentem zřetězení odkaz na objekt o:

    • je-li o == null : použije se řetězec null

    • je-li o != null : použije se hodnota vrácená metodou o.toString(), kterou lze překrýt a dosáhnout tak očekávaného řetězcového výstupu

Priority operátorů a vytváření výrazů

  • Motto: Pravidla priorit operátorů je dobré znát, ale ještě lepší je závorkovat, aby nedošlo k chybám a každý to přesně pochopil!

  • nejvyšší prioritu má násobení, dělení, nejnižší přiřazení

  • nízkou prioritu má ternární operátor booleovskýVýraz ? výrazProTrue : výrazProFalse

Pozn. Rozhodně NEZNEUŽÍVEJME přiřazení ve smyslu, že jej současně použijeme jako výraz, tzn. pracujeme s jeho hodnotu! Že to vůbec jde, je spíše reziduum převzaté do Javy z C.