Obsah
Primitivní vs. objektové typy
Kategorie primitivních typů: integrální, boolean, čísla s pohyblivou řádovou čárkou
Pole: deklarace, vytvoření, naplnění, přístup k prvkům, rozsah indexů
Java striktně rozlišuje mezi hodnotami
primitivních datových typů (čísla, logické hodnoty, znaky) a
objektových typů (řetězce a všechny uživatelem definované [tj. vlastní] typy-třídy)
Základní rozdíl je v práci s proměnnými:
proměnné primitivních typů přímo obsahují danou hodnotu, zatímco
proměnné objektových typů obsahují pouze odkaz na příslušný objekt
Důsledek -> dvě objektové proměnné mohou nést odkaz na tentýž objekt
Příklad, deklarujeme třídu
Cislo
takto:
public class Cislo {
private float hodnota;
public Cislo(float h) {
hodnota = h;
}
public void zvysO(float kolik) {
hodnota += kolik;
}
public void vypis() {
System.out.println(hodnota);
}
}
nyní ji použijeme:
Cislo c1 = new Cislo(1.23456);
Cislo c2 = c1;
c1.zvysO(2);
c1.vypis();
c2.vypis();
dostaneme:
3.23456
3.23456
Proměnné těchto typů nesou elementární, z hlediska Javy atomické, dále nestrukturované hodnoty.
V Javě jsou celá čísla vždy interpretována jako znaménková
"Základním" celočíselným typem je 32bitový int s rozsahem -2 147 483 648 až 2147483647
větší rozsah (64 bitů) má long, cca +/- 9*10^18
Pro celočíselné typy existují (stejně jako pro floating-point typy) konstanty - minimální a maximální hodnoty příslušného typu. Tyto konstanty mají název vždy Typ.MIN_VALUE , analogicky MAX... Viz např. Minmální a maximální hodnoty
Java vnitřně kóduje znaky a řetězce v UNICODE, pro vstup a výstup je třeba použít některou za serializací (převodu) UNICODE na sekvence bajtů:
např. vícebajtová kódování UNICODE: UTF-8 a UTF-16
osmibitová kódování ISO-8859-x, Windows-125x a pod.
Problém může nastat při interpretaci kódování znaků národních abeced přímo ve zdrojovém textu programu.
Ve zdroj. textu správně napsaného javového vícejazyčného programu by žádné národní znaky VŮBEC neměly vyskytovat.
Je vhodné umístit je do speciálních souborů tzv. zdrojů (v Javě objekty třídy java.util.ResourceBundle).
Kódována podle ANSI/IEEE 754-1985
Možné zápisy literálů typu float (klasický i semilogaritmický tvar) - povšimněte si "f" za číslem - je u float nutné!:
float f = -.777f, g = 0.123f, h = -4e6f, 1.2E-15f;
double: tentýž zápis, ovšem bez "f" za konstantou!, s větší povolenou přesností a rozsahem
Float.POSITIVE_INFINITY , totéž s NEGATIVE...
totéž pro Double
obdobně existují pro oba typy konstanty uvádějící rozlišení daného typu - MIN_VALUE , podobně s MAX...
Viz také Minimální a maximální hodnoty
Není v pravém slova smyslu datovým typem, nemá žádné hodnoty.
Označuje "prázdný" typ pro sdělení, že určitá metoda nevrací žádný výsledek.
Pole v Javě je speciálním objektem
Můžeme mít pole jak primitivních, tak objektových hodnot
Kromě pole v Javě existují i jiné objekty na ukládání více hodnot - tzn. kontejnery, viz dále
Poznámka | |
---|---|
na rozdíl od C/C++ nikdy neuvádíme při deklaraci počet prvků pole - ten je podstatný až při vytvoření objektu pole |
Syntaxe přístupu k prvkůmjménopole[indexprvku]Používáme
jak pro přiřazení prvku do pole: jménopole[indexprvku] = hodnota;
tak pro čtení hodnoty z pole proměnná = jménopole[indexprvku];
Syntaxe vytvoření objektu pole: jako u jiného objektu - voláním konstruktoru:
jménopole = new typhodnoty[ početprvků ]; nebo vzniklé pole rovnou naplníme hodnotami/odkazy
Pole je objekt, je třeba ho před použitím nejen deklarovat, ale i vytvořit:
Clovek[] lidi;
lidi = new Clovek[5];
lidi[0] = new Clovek("Václav Klaus", Clovek.MUZ);
lidi[1] = new Clovek("Libuše Benešová", Clovek.ZENA);
lidi[0].vypisInfo(); lidi[1].vypisInfo();
Co kdybychom pole pouze deklarovali a nevytvořili:
Clovek[] lidi;
lidi[0] = new Clovek("Václav Klaus", Clovek.MUZ);
Toto by skončilo s běhovou chybou "NullPointerException", pole neexistuje, nelze do něj tudíž vkládat prvky!
Pokud tuto chybu uděláme v rámci metody:
public class Pokus {
public static void main(String args[]) {
String[] pole;
pole[0] = "Neco";
}
}
Pokus.java:4: variable pole might not have been
initialized pole[0] = "Neco"; ^ 1 error
public class Pokus {
static String[] pole;
public static void main(String args[]) {
pole[0] = "Neco";
}
}
Překladač chybu neodhalí a po spuštění se objeví:
Exception in thread "main"
java.lang.NullPointerException at Pokus.main(Pokus.java:4)
Co kdybychom pole deklarovali, vytvořili, ale nenaplnili příslušnými prvky:
Clovek[] lidi;
lidi = new Clovek[5];
lidi[0].vypisInfo();
V Javě obecně přiřazení proměnné objektového typu vede pouze k duplikaci odkazu, nikoli celého odkazovaného objektu.
Clovek[] lidi2;
lidi2 = lidi1;
V proměnnélidi2je nyní odkaz na stejné pole jako je vlidi1.
Zatímco, provedeme-li vytvoření nového pole + arraycopy, pak lidi2 obsahuje duplikát/klon/kopii původního pole.
Clovek[] lidi2 = new Clovek[5];
System.arraycopy(lidi, 0, lidi2, 0, lidi.length);
viz též Dokumentace API třídy "System"
Poznámka | |
---|---|
Samozřejmě bychom mohli kopírovat prvky ručně, např. pomocí for cyklu, ale volání System.arraycopy je zaručeně nejrychlejší a přitom stále platformově nezávislou metodou, jak kopírovat pole. |
Také arraycopy však do cílového pole zduplikuje jen odkazy na objekty, nevytvoří kopie objektů!