2009-11-20

SCJP-6 01. Primityvų suderinamumas

Java turi aštuonis primityviuosius duomenų tipus:

  • byte
  • short
  • int
  • longint
  • float
  • double
  • char
  • boolean

Kiti duomenų tipai (įskaitant eilutes -- String) yra klasės/masyvai/interfeisai/enum, o visų jų realizacijų (arba paprasčiau tariant, objektų) hierarchijos viršūnėje stovi Object klasė.
Primityvieji duomenų tipai skirti saugoti konkrečią skaičiaus išraišką, išskyrus boolean tipą -- jis reprezentuoja vieną iš dviejų reikšmių (true arba false). Verta pastebėti, kad nors tipiškai char duomenų tipo kintamiesiems priskiriami simboliai, iš tiesų simbolių išraiška tėra kita skaičiaus išraiška. Todėl šis kodas -- teisingas:

int intHoldingChar = 'X';
char charHoldingNumber = 123;

Kitas dalykas -- vieni duomenų tipai gali talpinti skaičius iš platesnio rėžio, kiti -- iš siauresnio. Pavyzdžiui, byte duomenų tipui saugu priskirti reikšmes nuo -128 iki 127, o short -- nuo -32768 iki 32767. Akivaizdu, kad short tipo kintamajam visada saugu priskirti byte kintamojo reikšmę, bet ne atvirkščiai (nes short tipo kintamojo reikšmė gali išeiti iš byte tipui leidžiamų reikšmių rėžio). Antru atveju Java kompiliatorius reikalauja aiškaus tipo pažymėjimo (casting), nepaisant to, kad pati reikšmė ir patenka į leidžiamą rėžį:

short s = 123;
byte b1 = (byte) s; // viskas gerai
byte b2 = s; // kompiliavimo klaida

Kada yra saugu priskirti reikšmę tiesiogiai, o kada reikalingas casting'as?

double <- float <- long <- int <- (char, short <- byte)

Sekoje rodyklėmis pažymėta saugi priskyrimo kryptis -- t.y. int reikšmę galima tiesiogiai priskirti double tipo kintamajam. Duomenų tipo char rėžis yra 0...65536, tad jo reikšmę saugiai galima priskirti tik int arba aukštesnio tipo kintamajam. Tuo tarpu char kintamajam tiesiogiai negalima priskirti jokio kito tipo kintamojo reikšmės, mat net pats mažiausias byte tipo kintamasis potencialiai gali saugoti neigiamą skaičių (o char tipo kintamieji gali saugoti tik neneigiamus skaičius).
Todėl teisingi šie kodo pavyzdžiai:

// aiškus tipo pažymėjimas nebūtinas (bet nedraudžiamas)
byte b = 123;
short s = b;
int i = s;
int i2 = b;
long lng = b;
long lng2 = i2;
double d = b;
float f = lng;

// aiškus tipo pažymėjimas privalomas
byte xb = (byte) lng;
byte xb2 = (byte) d;
int xi = (int) f;

Komentarų nėra: