Java programozás 3. – Változók

Változók, avagy dobozok minden esetre

Ismerkedjünk meg a változókkal. A változóknak alapvetően két típusát különböztetjük meg: primitív és referencia. A referencia típusú változók nem egy egyszerű értére mutatnak, hanem egy összetettebb adatszerkezetre, maga a változó csak egy hivatkozás az adatszerkezet memóriabeli címére. Most a primitív változókat fogjuk tárgyalni.

A programunkban szinte mindig előfordul az, hogy valamilyen adatot tárolni szeretnénk. Az elméleti bevezetés cikkben foglalkoztunk azzal, hogy a Java egy objektum orientált programozási nyelv. Az objektumok pedig rájuk jellemző tulajdonságokból és az ezeket kezelő (beállító, lekérdező, módosító) metódusokból állnak. Ezeket a tulajdonságokat mi rendeljük hozzá az objektumokhoz, hiszen mi döntjük el, miket kívánunk használni. Minden tulajdonságot alapvetően három fontos elem határoz meg. A tulajdonság típusa, neve és értéke. A változó a háttérben valójában egy memóriaterület, ami valamilyen értéket tárol. Felsorolásképp nézzünk meg pár fontos megállapítást a változókkal kapcsolatban:

  • A változók neve egyedi kell hogy legyen (adott blokkon belül), csak betűvel kezdődhet, de utána bármennyi és bármilyen karakter állhat.
  • A változók értéke alapvetően nem fix, ezt módosíthatjuk, erre utal a változó név. (léteznek fix változók is, melyek értékét csak egyszer adhatjuk meg.)
  • Minden változó egy időpontban egyetlen értéket tárolhat. Ha új értéket adunk neki, az előző érték törlődik.

A változó neve a programunkon belül minden esetben a benne tárolt értéket jelenti. Ahol a változó nevét a programba illesztjük, ott az abban tárolt értéket fogja felhasználni. Említettem, hogy a változó típussal, névvel és értékkel rendelkezik. Ebből a típusról nem volt még szó. A típus azt határozza meg, hogy milyen jellegű értéket tárolhatunk az adott változóban. A primitív változók alapvetően négyféle típusúak lehetnek, egy-egy konkrét példával:

  • egész szám: 32
  • valós szám: 1.125
  • karakter: c
  • logikai érték: true

Ezek az alaptípusok, de az egész és valós számok váltózói a bennük tárolt szám nagyságától függően még tovább bonthatók. Az egész számok egész értékeket tárolnak tizedesjegyek nélkül. A valós számok tizedesjegyekkel rendelkező számokat jelentenek. A karakter típusú változó valamilyen billentyűzeten lévő begépelhető karaktert tárolhat (betűk, számok, írásjelek, speciális karakterek, szóköz, stb), valamint speciális, önmagában be nem gépelhető vezérlő karaktereket tartalmazhat. A logikai érték pedig egy kétállású kapcsoló, mely igaz vagy hamis értékeket tárolhat, pontosabban ezek angol nyelvű megfelelőjét (true, false).

A változó tehát egy típussal, névvel és a típus által meghatározott értékkel rendelkező adatelem. Nézzünk a változók használatára egy példát. Vegyünk egy autó objektumot és pár ahhoz tartozó tulajdonságot. Legyen az autónak sebességfokozata, pillanatnyi sebessége, színkódja, és egy jelző, ami a színkódot bővíti ki, hogy metálfényű-e vagy sem. Ebben a példakódban mind a négy alaptípus megtalálható.

public class Auto
{
  public static void main( String[] args )
  {
    int fokozat;
    double sebesseg;
    char szinkod;
    boolean metal;

    System.out.println("Ez egy virtualis auto.");

    fokozat = 4;
    sebesseg = 48.6;
    szinkod = 'R';
    metal = true;

    System.out.println( "Az auto sebessegfokozata: " + fokozat );
    System.out.println( "Az auto pillanatnyi sebessege: " + sebesseg );
    System.out.println( "Az auto szinkodja: " + szinkod );
    System.out.println( "Az auto metalszinu: " + metal );
  }
}

A változók használatával kapcsolatban két nagyon fontos fogalmat kell tisztázni:

  • deklarálás
  • inicializálás

A deklarálás a változó típusának és nevének megadását jelenti. Ennek általános formája:
típus változónév;
Az inicializálás a változónak történő kezdőérték adás. Általános formája:
változónév = kezdőérték;
Ez a két lépés akár össze is vonható, ekkor a következőt írjuk:
típus változónév = kezdőérték;

A változók tekintetében fontos ügyelni arra, hogy addig ne használjuk – nem is nagyon tudjuk – a változót, amíg nem rendelkezik kezdőértékkel, ami akár nulla vagy típustól függően speciális null (üres) érték is lehet. Használatnak minősül az is, ha a változó értékét ki szeretnénk íratni a képernyőre. A változó értékét természetesen többször is meg lehet változtatni, ilyenkor az előző érték, mint már említettem, törlődik. Ez az értékadás formailag ugyanolyan, mint az inicializálás. A különbség a kettő között csak annyi, hogy az inicializálás a legelső értékadás.

Ahogy már említettem, a változó nevét használva a benne tárolt értéket kaphatjuk meg. Amikor például ki szeretnénk írni, hogy milyen értéket tárol, akkor a következőt tesszük:

"Az auto sebessegfokozata: " + fokozat

Az idézőjelek közötti szövegrészt String-nek nevezzük. Ez egy karakterekből álló karakterlánc (szövegnek is nevezik, bár nem csak betűket tartalmazhat). A String egy referencia változótípus, később fogjuk tárgyalni, most elég annyit tudni róla, hogy amit idézőjelek közé teszünk, az String típusú lesz. Azért fontos ez, mert jellemzően szövegeket írunk ki a képernyőre. Látjuk azt azonban, hogy a szöveghez “hozzáadjuk” a változót. A Java nyelvben a műveletek többségét (csakúgy, mint matematikában) balról jobbra értékeljük ki. Ekkor az történik, hogy a megadott szöveghez hozzáfűzi a változó értékét. De nem csak ennyi történik, hanem egy nagyon fontos dolog is!

Az összeadás, mint művelet itt összefűzést jelent, vagyis a változó tartalmát odailleszti a szöveg végére. De a szöveg és a példában említett fokozat nevű változó nem egyforma típusú. Az összefűzés során a számérték szöveg típusúvá alakul egy automatikus konverziót (típusváltást) követően. Ezért lehet így kiíratni a változók értékét.

Még a primitív változóknál is léteznek adott típuson belül különféle “méretű” tárolók. Attól függetlenül, hogy egy változó mondjuk egész számokat tartalmazhat, meg lehet adni a méretét is. A mérete alatt azt értjük, hogy a számítógép hány bájton tárolja a szám értékét, ezáltal meghatározza azt az intervallumot, amekkora értéket a változó felvehet. Egész típuson belül a következő állnak rendelkezésünkre:

Típus Leírás Tárolás Intervallum
byte bájt méretű egész 8 bit [-128;127]
short rövid egész 16 bit [-32768;32767]
int egész 32 bit [-2147483648;2147483647]
long hosszú egész 64 bit [-9223372036854775808;9223372036854775807]

Az egész típusokhoz hasonlóan lebegőpontos számokat tartalmazó változóból is többféle, szám szerint kettő van.

Típus Leírás Tárolás
float egyszeres pontosságú lebegőpontos 32 bit
double kétszeres pontosságú lebegőpontos 64 bit

Mivel azonos típusból többféle méret létezik, már a kezdőérték megadásakor problémák lehetnek. Vegyük ezt a példát:

int szam = 10;

Ezzel semmi gond nincs, ugyanis az int típusba ez a méretű szám elfér. A byte és short típusoknál is hasonlóan lehet megadni kezdőértéket, arra kell csak ügyelni, hogy megfelelő méretű számot tároljunk csak benne. Az utolsóval már gond lenne, mert a tárolni kívánt érték már nincs benne a változónak megfelelő intervallumban.

  1. byte b = 10;
  2. byte b = -40;
  3. byte b = 120;
  4. byte b = 130;

A short típussal is hasonló a helyzet, ott például már nem lehetne egy 35000 értéket tárolni, mert nem fér el ebben a típusú változóban.

Mi a helyzet a long típussal? Egy érdekes hibába futhatunk bele egy ilyen sorral

long szam = 3000000000;

Tegyük fel, egy 3 milliárdos kezdőértéket akarunk adni. Fura, hiszen a változóban sokkal nagyobb méretű szám is beleférne. Ez a 3 milliárd melyik változónak az intervallumából log ki? Az int típuséból. Arról van szó, hogy ha csak egy számot leírunk mindenféle sallang nélkül, azt a Java int típusú értékként kezeli. A kisebb számoknál akkor hogyan oldja meg, hogy egy byte változóba belerakhatja a nagyobb méretű int típusú értéket? Konverzióval, vagyis a byte változóban már az átalakított, megfelelő méretű értéket helyezi el. Igen ám, de maradva az előző hibánál itt a gond az, hogy ekkora méretű int szám nem is létezik, ezért el sem fogadja így leírva. Ekkor külön jeleznünk kell a számérték végén a szám típusát a következőképp:

long szam = 3000000000L;

A leírt fix értékeket (nem csak ezeket, általában a leírt fix értékeket) literálnak nevezzük. Ez a long típus literálja. Középiskolában ekkora számokkal nem dolgozunk, de jó ha tudsz erről. Érdekes módon a Java a 10L helyett a 10l literált is elfogadja, holott alaphelyzetben a kis és nagybetűk között különbséget tesz.

A változók, mint adott méretű tárolók természetesen csak a nekik megfelelő méretű számokat képesek tárolni. A nagyobb méretű tárolókba elhelyezhetjük egy kisebb méretű változó értékét, de fordítva ez nem fordulhat elő, mert már fordítási hibával figyelmeztet a rendszer:

int i = 10;
short s = i;

Összefoglalva tehát az egész számokat:

  • négyféle méretű típusa létezik
  • nagyobb méretű típusba be lehet tenni a kisebbet, fordítva nem
  • a számokkal megadott literál int típusú, ha long típust szeretnél akkor 10L

A lebegőpontos számok esetén is hasonló a helyzet. Itt a jelzés nélküli literál alaphelyzetben double típust jelent: 10.0 Ha azonban mindenképpen float típust szeretnénk, akkor a 10F vagy 10f literál használatos. Itt is fordítási hibát ad, ha a nagyobb méretet a kisebb méretűben szeretnénk elhelyezni:

double d = 10.0;
float f = d;

Tizedesvessző helyett tizedes pontot használunk, valamit nem kötelező ezt sem megadni ebben az esetben:

double d = 10D;
float f = 10F;

Itt látszólag egész számot adunk kezdőértéknek, de a 10D literál miatt ez a 10.0 lesz valójában, vagy float típusnál hasonlóan csak kisebb méretben. Float típus értékmegadásánál viszont a literálnál kötelező ezt a formát használni, mivel az F elhagyásakor a számot alapból double méretűként kezelné a rendszer, ami viszont a float-ba nem fér bele. Ez a példa ezt a hibás használatot mutatja meg a jó megoldással együtt:

float f = 10.3;  // hibás!
float f = 10.3F; // helyes

Következő lecke: Kiíratás alapjai

2 Replies to “Java programozás 3. – Változók”

  1. Szia, nagyon jó a magyarázat és alapos az anyag. Viszont ez az állítás szerintem fordítva igaz: “•nagyobb méretű típust be lehet tenni a kisebbe, fordítva nem”

Vélemény, hozzászólás?

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük

*

Ez az oldal az Akismet szolgáltatást használja a spam csökkentésére. Ismerje meg a hozzászólás adatainak feldolgozását .