Typ Vymazanie v jazyku Java Vysvetlenie

1. Prehľad

V tomto rýchlom článku sa budeme zaoberať základmi dôležitého mechanizmu v generike Javy, ktorý sa nazýva mazanie typov.

2. Čo je to vymazanie typu?

Vymazanie typu možno vysvetliť ako proces vynucovania obmedzenia typu iba v čase kompilácie a vyradenia informácií o type prvku za behu.

Napríklad:

public static boolean containsElement (E [] elements, E element) {for (E e: elements) {if (e.equals (element)) {return true; }} return false; }

Kompilátor nahradí neviazaný typ E so skutočným typom Objekt:

public static boolean containsElement (Object [] elements, Object element) {for (Object e: elements) {if (e.equals (element)) {return true; }} return false; }

Preto kompilátor zaisťuje typovú bezpečnosť nášho kódu a predchádza chybám pri behu.

3. Typy vymazania typu

K vymazaniu typu môže dôjsť na úrovni triedy (alebo premennej) a metódy.

3.1. Vymazanie typu triedy

Na úrovni triedy kompilátor zahodí parametre typu v triede a nahradí ich prvou väzbou, príp Objekt ak je parameter typu neviazaný.

Implementujme a Stoh pomocou poľa:

public class Stack {private E [] stackContent; public Stack (int kapacita) {this.stackContent = (E []) nový objekt [kapacita]; } public void push (dáta E) {// ..} public E pop () {// ..}}

Po kompilácii kompilátor nahradí parameter neviazaného typu E s Objekt:

public class Stack {private Object [] stackContent; public Stack (int kapacita) {this.stackContent = (Object []) nový objekt [kapacita]; } public void push (dáta objektu) {// ..} public Object pop () {// ..}}

V prípade, že parameter typu E je zviazaný:

verejná trieda BoundStack {private E [] stackContent; public BoundStack (int kapacita) {this.stackContent = (E []) nový objekt [kapacita]; } public void push (dáta E) {// ..} public E pop () {// ..}}

Kompilátor nahradí parameter viazaného typu E s prvou viazanou triedou, Porovnateľné v tomto prípade:

verejná trieda BoundStack {private Comparable [] stackContent; public BoundStack (int kapacita) {this.stackContent = (porovnateľný []) nový objekt [kapacita]; } public void push (porovnateľné údaje) {// ..} verejné porovnateľné pop () {// ..}}

3.2. Vymazanie typu metódy

Pre vymazanie typu na úrovni metódy sa parameter typu metódy neuloží, ale sa prevedie na nadradený typ Objekt ak je neviazaný alebo je to prvá viazaná trieda, keď je viazaný.

Uvažujme o spôsobe zobrazenia obsahu ľubovoľného daného poľa:

public static void printArray (E [] pole) {for (E element: array) {System.out.printf ("% s", element); }}

Po kompilácii kompilátor nahradí parameter typu E s Objekt:

public static void printArray (Object [] array) {for (Object element: array) {System.out.printf ("% s", element); }}

Pre parameter typu viazanej metódy:

verejná statická  void printArray (E [] pole) {for (E element: array) {System.out.printf ("% s", element); }}

Budeme mať parameter typu E vymazané a nahradené Porovnateľné:

public static void printArray (Comparable [] array) {for (Comparable element: array) {System.out.printf ("% s", element); }}

4. Prípady hrán

Niekedy počas procesu mazania typu kompilátor vytvorí syntetickú metódu na odlíšenie podobných metód. Môžu pochádzať z podpisov metód rozširujúcich tú istú prvú viazanú triedu.

Vytvorme novú triedu, ktorá rozširuje našu predchádzajúcu implementáciu Stoh. Upozorňujeme, že sa to týka Stoh triedy, ktorú sme vytvorili v oddiel 3.1, a nie java.util.Stack.

public class IntegerStack extends Stack {public IntegerStack (int kapacita) {super (kapacita); } public void push (celočíselná hodnota) {super.push (hodnota); }}

Teraz sa pozrime na nasledujúci kód:

IntegerStack integerStack = nový IntegerStack (5); Stack stack = integerStack; stack.push ("ahoj"); Celé dáta = integerStack.pop ();

Po vymazaní typu máme:

IntegerStack integerStack = nový IntegerStack (5); Hromadný stoh = (IntegerStack) integerStack; stack.push ("ahoj"); Celé dáta = (String) integerStack.pop ();

Všimnite si, ako môžeme tlačiť a String na IntegerStack - pretože IntegerStack zdedil push (objekt) z materskej triedy Stoh. To je samozrejme nesprávne - pretože by to malo byť celé číslo integerStack je a Stoh typu.

Takže neprekvapujúco, pokus o pop a String a priradiť k Celé číslo spôsobuje a ClassCastException z obsadenia vloženého počas tam kompilátorom.

4.1. Mostné metódy

Na vyriešenie vyššie uvedeného okrajového prípadu kompilátor niekedy vytvorí mostovú metódu. Toto je syntetická metóda vytvorená kompilátorom Java pri kompilácii triedy alebo rozhrania, ktorá rozširuje parametrizovanú triedu alebo implementuje parametrizované rozhranie, kde podpisy metód môžu byť mierne odlišné alebo nejednoznačné.

V našom príklade vyššie kompilátor Java zachováva polymorfizmus generických typov po vymazaní tým, že zaisťuje, že nedôjde k nesúladu podpisu metódy medzi IntegerStack‘S push (celé číslo) metóda a Stoh‘S push (objekt) metóda.

Preto tu kompilátor vytvára premosťovaciu metódu:

verejná trieda IntegerStack rozširuje metódu Stack {// Bridge generovanú kompilátorom public void push (hodnota objektu) {push ((celé číslo) hodnota); } public void push (celočíselná hodnota) {super.push (hodnota); }}

V dôsledku toho Stoh triedy tam metóda po vymazaní typu, deleguje na originál tam metóda IntegerStack trieda.

5. Záver

V tomto tutoriáli sme diskutovali o koncepcii mazania typov s príkladmi v premenných parametrov a metódach typu.

Môžete si prečítať viac o týchto konceptoch:

  • Špecifikácia jazyka Java: Vymazanie typu
  • Základy generických jazykov Java

Zdrojový kód, ktorý je priložený k tomuto článku, je ako vždy k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found