Proměnné objektových a primitivních typů

Lokální proměnné vs. atributy

Liší se:

  • v dostupnosti (scope): Celá třída (atribut) vs. aktuální blok (lokální proměnné a parametry metod).

  • v možnosti kolize jmen: Jméno atributu může kolidovat s lokální proměnnou/parametrem, lokální proměnné ale stejná jména mít nesmí.

  • v iniciální hodnotě: Číselné atributy jsou inicializovány na nulu, boolean na false, objektové na null. U lokálních proměnných toto neplatí.

  • okamžikem vytvoření: Lokální proměnné se vytvoří na zásobníku se při každém zavolání metody, atributy vzniknout na haldě při vytvoření objektu.

Primitivní vs. objektové proměnné

Primitivní proměnné:

  • Obsahují přímo danou hodnotu.

  • Předávají se hodnotou (kopíruje se obsah do nové proměnné).

Objektové proměnné:

  • Obsahují adresu objektu nebo null.

  • Předávají se odkazem (kopíruje se obsah, tj. adresa, do nové proměnné a tudíž nová proměnná odkazuje na původní objekt).

Objektové obálky nad primitivními hodnotami

  • Ke každému primitivnímu typu int, char, double apod. existuje varianta objektového typu — Integer, Character, Double, …​

  • Tyto objektové typy se nazývají wrappers.

  • Při vytváření takových objektů není nutné používat new,

    • využije se tzv. autoboxing, např. Integer five = 5;

    • Obdobně autounboxing, int alsoFive = five;

Integer objectInt = new Integer(42);
Integer objectInt2 = 42;

Odvození typu

  • Doposud jsme viděli, že proměnná má jasně deklarovaný typ.

  • V novějších verzích Javy (8+) lze využít tzn. odvození typu (type inference).

Person petr = new Employee("Petr Servus");
// compiles successfully
petr = new Person("Petr Svatý");
var petr = new Employee("Petr Servus");
// so this does not compile - Employee expected:
petr = new Person("Petr Svatý");

Odvození typového parametru

  • Kromě výše uvedených jednoduchých situací uvidíme později další.

  • U tzv. parametrizovaných typů, např. seznamů, lze odvodit typ prvku seznamu z jedné strany na druhou - i zleva doprava.

List<Person> listPeople = new ArrayList<>();
// or the type on the left is inferred to ArrayList<Person>
var listPeople = new ArrayList<Person>();

Odvození typu lambda výrazu

  • Lambda výrazy (konstrukcty funkcionálního paradigmatu) jsou také typované.

  • Funguje zde odvození typů - zde se odvodí, že v seznamu jsou osoby:

var listPeople = new ArrayList<Person>();
// type of the list item is Person
// inferred type of lambda is `(Person p) -> p.print()`:
listPeople.forEach(p -> p.print());