Úvod k datovým typům v Javě
-
Existují dvě základní kategorie datových typů: primitivní a objektové
-
v proměnné je uložena přímo hodnota
-
např.
int
,long
,double
,boolean
, …
-
musí se nejdřív zkonstruovat (použitím
new
) -
do proměnné se uloží pouze odkaz
-
např.
String
,Person
, …
Datové typy primitivní
- integrální typy
-
zahrnují typy celočíselné (byte , short , int a long) a typ char
- čísel s pohyblivou řádovou čárkou
-
float a double
- logických hodnot
-
boolean
Výchozí (default) hodnoty
-
Každý typ má svou výchozí (default) hodnotu, na kterou je nastaven, není-li hned přiřazena jiná.
-
Dle Java Language Specification: Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10):
-
For type
byte
, the default value is zero, that is, the value of(byte)0
. -
For type
short
, the default value is zero, that is, the value of(short)0
. -
For type
int
, the default value is zero, that is,0
. -
For type
long
, the default value is zero, that is,0L
. -
For type
float
, the default value is positive zero, that is,0.0f
. -
For type
double
, the default value is positive zero, that is,0.0d
. -
For type
char
, the default value is the null character, that is,'\u0000'
. -
For type
boolean
, the default value isfalse
. -
For all reference types (§4.3), the default value is
null
-
Na co se vztahují výchozí hodnoty
-
Automatické nastavení proměnných na výchozí hodnoty se tedy vztahuje na proměnné objektů a tříd (atributy) a prvky polí.
-
Nevztahuje se na lokální proměnné a parametry, ty musejí být před prvním použitím nastaveny, inicializovány.
Příklad výchozí hodnoty
int i; // automatically i = 0
Více informací najdete na: The Java Tutorials: Primitive Data Types. |
Zajímavosti a odlišnosti
-
V Javě neexistuje možnost typy rozsahově či interpretačně modifikovat (žádné unsigned int apod.)
-
Pro velká čísla lze v nových verzích Javy použít notaci s podtržítkem k oddělení řádů po tisících:
private int bigNumber = 123_456_789;
Datové typy objektové
-
objektovými typy v Javě jsou všechna ostatní typy
-
třídy
-
rozhraní ("téměř totéž, co třídy")
-
pole (ano, v Javě jsou samotná pole objekty)
Výchozí hodnota objektového typu je null
— tzv. "ukazatel na nic".
Příklad použití objektového typu
Person p; // p is null automatically
p = new Person(); // now p references to an object
-
Objektový typ je všechno, kde se používá operátor
new
.
Shrnutí
Základní rozdíl je v práci s proměnnými.
- primitivní typy
-
přímo obsahují danou hodnotu
- objektové typy
-
obsahují pouze odkaz na příslušný objekt
-
Důsledek: dvě objektové proměnné mohou nést odkaz na tentýž objekt
-
Přiřazení primitivní proměnné
-
Hodnota proměnné se nakopíruje:
double a = 1.23456;
double b = a;
a += 2;
// a is 3.23456
// b is 1.23456
Přiřazení objektové proměnné
-
Objektové proměnné ukazují na stejný objekt:
public class Counter {
private double value;
public Counter(double v) {
value = v;
}
public void add(double v) {
value += v;
}
}
...
Counter c1 = new Counter(1.23456);
Counter c2 = c1;
c1.add(2);
// c1 has value 3.23456
// c2 has value 3.23456
Operátor ==
-
Pro primitivní typy porovnává hodnoty:
1 == 1 // true
1 == 2 // false
-
Pro objektové typy porovnává odkazy:
Counter c1 = new Counter(1.23456);
Counter c2 = c1;
c1 == c2 // true
c1 == new Counter(1.23456) // false
-
Na porovnání hodnot objektových typů se používá
equals
, probereme později.
Pole v zkratce
-
Vytvoření, naplnění a získání hodnot vypadá následovně:
int[] array = new int[2];
array[0] = 1;
array[1] = 4;
System.out.println("First element is: " + array[0]);
-
Deklarace: typ[] jméno =
new
typ [velikost]; -
typ může být i objektový:
Person[] p = new Person[3];
Velikost pole
-
velikost pole je daná při jejím vytvoření a nelze ji měnit
-
V budoucnu budeme probírat kolekce (seznam, slovník), což je mocnější složený datový typ než pole
-
jejich počty prvků se mohou dynamicky měnit
Mělká kopie
-
Přiřazení proměnné objektového typu (což je i pole) vede pouze k duplikaci odkazu, nikoli celého odkazovaného objektu.
-
Modifikace jedné proměnné se pak projeví u i té druhé.
int[] array = new int[] {1, 4, 7};
int[] array2 = array;
array[1] = 100;
System.out.println(array[1]); // prints 100
System.out.println(array2[1]); // prints 100
-
Takovému kopírování se říká mělká kopie (shallow copy).
Hluboká kopie
Provedeme-li vytvoření nového pole, pak array2 obsahuje kopii (duplikát) původního pole.
int[] array = new int[] {1, 4, 7};
int[] array2 = Arrays.copyOf(array, array.length);
array[1] = 100;
System.out.println(array[1]); // prints 100
System.out.println(array2[1]); // prints 4
-
Takovému kopírování se říká hluboká kopie (deep copy).
Metoda copyOf
bere dva parametry — původní pole a počet prvků, kolik se má nakopírovat.
Hluboká kopie u objektů I
-
Obdobně to funguje i objektů.
Person[] people = new Person[] { new Person("Jan"), new Person("Adam")};
Person[] people2 = Arrays.copyOf(people, people.length);
people[1] = new Person("Pepa");
System.out.println(people[1].getName()); // prints Pepa
System.out.println(people2[1].getName()); // prints Adam
-
Co kdybychom změnili jenom jméno (atribut objektu)?
Hluboká kopie u objektů II
-
Do cílového pole se zduplikují jenom odkazy na objekty Person, nevytvoří se kopie objektů Person!
Person[] people = new Person[] { new Person("Jan"), new Person("Adam")};
Person[] people2 = Arrays.copyOf(people, people.length);
people[1].setName("Pepa"); // changes Adam to Pepa
System.out.println(people[1].getName()); // prints Pepa
System.out.println(people2[1].getName()); // prints Pepa
-
Jinými slovy, pole mají sice různý odkaz (šipku), ale na stejný objekt.
-
V předešlém příkladu jsme změnili odkaz na jiný objekt.
-
Teď jsme změnili obsah objektu, na který ukazují oba odkazy.