5. Kifejezések, utasítások, blokkok

A változók és az operátorok, amelyekkel az előző fejezetben ismerkedhettünk meg, a programok alapvető építőkövei. Változók, literálok és operátorok kombinációiból hozzuk létre a kifejezéseket vagy kódszegmenseket, amelyek számításokat végeznek, és értékeket adnak vissza. Néhány kifejezés utasításokba szervezhető. Ezek komplett futtatási egységek. Ezeket az utasításokat kapcsos zárójelek közé csoportosítva { és } kapjuk meg az utasításblokkokat.

5.1. Kifejezések

A kifejezések hajtják végre a program feladatát. A kifejezéseket többek között változók kiszámítására, értékük beállítására és a program futásának ellenőrzésére használjuk. A kifejezéseknek kétféle feladata van: végrehajtani a számításokat, amelyeket a kifejezés alkotóelemi határoznak meg, és visszaadni a számítás végeredményét.

A kifejezés változók, operátorok és metódushívások olyan sorozata (a nyelv szintaxisát figyelembe véve) amely egy értéket ad vissza.

Ahogy az előzőekben már említettük, az operátorok egy értéket adnak vissza, így az operátor használatával egy kifejezést kapunk. A MaxVariablesDemo program részlete néhányat bemutat a program kifejezései közül:

...
char aChar = 'S';
boolean aBoolean = true;

System.out.println("The largest byte value is " + largestByte);
...

if (Character.isUpperCase(aChar)) {
    ...
}

A kifejezések kiértékelése során végrehajtásra kerülnek műveletek, és a kifejezés visszaad egy értéket, mint az a következő táblázatban is látható:

Kifejezés

Művelet

Visszaadott
érték

aChar = 'S'

Az 'S' karaktert adja értékül az aChar karakter típusú változónak

aChar értéke az értékadás után ('S')

"The largest byte
value is " + largestByte

Összefűzi a sztringet és a largestByte értékét sztringgé konvertálva

Az eredmény az összefűzött sztring

Character.isUpperCase(aChar)

isUpperCase metódus hívása

A metódus visszatérési értéke: true

A kifejezés által visszaadott érték adattípusa függ a kifejezésben használt alkotóelemektől. Az aChar = 'S' kifejezés egy karaktert ad vissza, mert az értékadó operátor ugyanolyan típusú értékkel tér vissza, mint amilyenek az operandusai, és az aChar valamint az 'S' karakter típusúak. A többi kifejezésnél már láthattuk, hogy egy kifejezés egy boolean értékkel, egy sztringgel és egyéb értékekkel is visszatérhet.

A Java nyelv lehetőséget biztosít összetett kifejezések és utasítások létrehozására kisebb kifejezésekből, amíg a kifejezés egyik részében használt adattípusok megegyeznek a többi rész adattípusaival. Itt láthatunk egy példát összetett kifejezésre:

x * y * z

Ebben a különleges példában a sorrend, amely szerint a kifejezés kiértékelődik, nem fontos, mivel a szorzás eredménye nem függ a tagok sorrendjétől, a végeredmény mindig ugyanaz, nem számít, milyen sorrendben végezzük el a szorzásokat. Azonban ez nem minden kifejezésre igaz. Például a következő kifejezés különböző eredményt ad attól függően, hogy az összeadás vagy az osztást megvalósító operátor hajtódik-e végre elsőként:

x + y / 100

Zárójelezéssel meghatározhatjuk, hogy egy kifejezés hogyan értékelődjön ki. Például így tehetjük egyértelművé a végrehajtást az előző példa esetében:

(x + y)/ 100

Ha határozattan nem jelezzük a sorrendet, amely szerint akarjuk, hogy az összetett kifejezés kiértékelődjön, akkor a sorrendet az operátorok precedenciája fogja meghatározni. A magasabb precedenciával rendelkező operátorok hajtódnak végre elsőként. Például az osztás operátor magasabb precedenciájú, mint az összeadás. Így a következő két kifejezés megegyezik egymással:

x + y / 100
x + (y / 100)

Ha összetett kifejezést írunk, akkor kifejezetten figyelnünk kell a zárójelezésre és arra, hogy mely operátoroknak kell kiértékelődniük elsőként. Ennek a gyakorlása segíthet a forráskód jobb olvashatóságának és karbantarthatóságának elérésében.

A következő táblázat a Java platformban használt operátorok precedencia-szintjeit mutatja be. Az operátorok a táblázatban precedencia-szint szerint vannak rendezve: legfelül a legnagyobb precedenciával rendelkező található. A magasabb precedenciával rendelkező operátorok előbb hajtódnak végre, mint az alacsonyabbal rendelkezők. Az azonos szinten elhelyezkedő operátorok azonos precedenciával rendelkeznek. Ha azonos precedenciájú operátorok szerepelnek egy kifejezésben, akkor szabályozni kell, hogy melyik értékelődjön ki elsőként. Minden bináris operátor, kivéve az értékadó operátorokat balról jobbra hajtódnak végre. Az értékadó operátorok jobbról balra hajtódnak végre.

Operátor precedencia szintek

postfix

expr++ expr--

unáris

++expr --expr +expr -expr ~ !

multiplikatív

* / %

additív

+ -

léptetés

<< >> >>>

relációs

< > <= >= instanceof

egyenlőség

== !=

bitenkénti és

&

bitenkénti kizáró vagy

^

bitenkénti vagy

|

logikai és

&&

logikai vagy

||

feltételes

? :

értékadás

= += -= *= /= %= &= ^= |= <<= >>= >>>=

5.2. Utasítások

Az utasítások nagyjából a beszélt nyelv mondatainak felelnek meg. Az utasítás egy konkrét futási egységet hoz létre. A következő kifejezéstípusok szervezhetők utasításokba, amelyek pontosvesszővel (;) végződnek:

  • értékadó kifejezések
  • ++ és -- használata
  • metódushívások
  • objektumot létrehozó kifejezések

Az utasításoknak ezt a fajtáját kifejezés utasításoknak nevezzük. Itt láthatunk pár példát a kifejezés-utasításokra:

aValue = 8933.234;                      //értékadó utasítás
aValue++;                               //növelés      
System.out.println(aValue);             //metódus hívás    
Integer integerObject = new Integer(4); //objektum létrehozás

A kifejezés-utasításokon kívül még kétféle típust kell megemlítenünk. A deklarációs utasítás létrehoz egy változót. Sok példát láthattunk már deklarációs utasításokra.

double aValue = 8933.234;             //deklarációs utasítás

A végrehajtás-vezérlő utasítás szabályozza, hogy az utasítások milyen sorrendben hajtódnak végre. A for ciklus és az if utasítás jó példák a végrehajtás-vezérlő szerkezetre.

5.3. Blokkok

A blokk nulla vagy több utasítás kapcsos zárójelek között, amely használható bárhol, ahol az önálló utasítások megengedettek. A következő részlet két blokkot mutat be a MaxVariablesDemo programból, mindegyik tartalmaz egy önálló utasítást:

if (Character.isUpperCase(aChar)) {
    System.out.println("The character " + aChar + " is upper case.");
} else {
    System.out.println("The character " + aChar + " is lower case.");
}

5.4. Összefoglalás

Egy kifejezés változók, operátorok és metódushívások sorozata (a nyelv szintaxisát figyelembe véve), amely egy értéket ad vissza. Írhatunk összetett kifejezéseket is egyszerűbbekből összeállítva mindaddig, amíg a magában foglalt, az operátorokhoz szükséges adattípusok megfelelőek. Ha összetett kifejezést írunk, akkor kifejezetten figyelnünk kell a zárójelezésre és arra, hogy mely operátoroknak kell kiértékelődniük elsőként.

Ha nem használjuk a zárójelezést, akkor a Java platform az operátorok precedenciája szerint értékeli ki az összetett kifejezést. A korábbi táblázat mutatja be a Java platformban megtalálható operátorok precedenciáját.

Az utasítás egy konkrét utasítási egységet valósít meg, amelyet pontosvessző zár le (;). Az utasításoknak három fajtája van: kifejezés utasítások, deklarációs utasítások, végrehajtás-vezérlő utasítások.

Nulla vagy több utasításból a kapcsos zárójelek segítségével blokkokat alakíthatunk ki: { és }. Habár nem szükséges, ajánlott az alkalmazása akkor is, ha a blokk csak egy utasítást tartalmaz.

5.5. Ellenőrző kérdések

  • Mit jelent a programblokk?
  • Hogyan kell egy programblokkot leírni Jávában?
  • Mondjon példát kifejezés-utasításra!
  • Kell e pontosvesszőt (;) írni egy kifejezés végére?
  • Azonos precedenciájú operátorok esetén mikor fog jobbról balra haladni a kiértékelés?

A következő sorok közül melyik fog hiba nélkül lefordulni?

  • float f=1.3;
  • char c="a";
  • byte b=257;
  • boolean b=null;
  • int i=10;