Programovanie

JDK 7: Diamantový operátor

Project Coin poskytuje početné „vylepšenia malého jazyka“ ako podmnožinu nových funkcií JDK 7. Nedávno som blogoval o tom, ako Project Coin zapína Strings a v tomto príspevku píšem o novom Diamond Operator ().

Diamantový operátor znižuje niektoré výroky Javy okolo generík tým, že dáva kompilátoru odvodiť typy parametrov pre konštruktory generických tried. Pôvodný návrh na pridanie operátora Diamond do jazyka Java bol vypracovaný vo februári 2009 a obsahuje tento jednoduchý príklad:

Zvážte napríklad nasledujúce vyhlásenie o priradení:

Mapa anagramy = nový HashMap();

Toto je dosť zdĺhavé, takže ho možno nahradiť týmto:

Mapa anagramy = nový HashMap ();

Vyššie uvedený príklad uvedený v návrhu Jeremyho Mansona (ktorý bol jedným z prvých v reakcii na výzvu na predloženie nápadov na Project Coin) je jednoduchý, ale adekvátne demonštruje, ako sa diamantový operátor uplatňuje v JDK 7. Mansonov návrh tiež poskytuje významné informácie o tom, prečo tento dodatok bolo žiaduce:

Požiadavka, aby sa parametre typu zbytočne duplikovali

toto podporuje nešťastníka

nadbytok statických továrenských metód, jednoducho preto, že sa odvodzuje typ

pracuje na vyvolaní metód.

Inými slovami, pridanie diamantového operátora do JDK 7 Project Coin prináša odvodenie typu od konštruktorov, ktoré boli k dispozícii s metódami. Pri metódach sa odvodenie typu implicitne vykoná, keď sa vynechá explicitná špecifikácia typu parametra. Na druhej strane s inštanciou musí byť operátor diamantu výslovne uvedený, aby „povedal“ kompilátoru, aby odvodil typ.

Vo svojom pôvodnom návrhu Manson poukazuje na to, že syntax bez špeciálneho operátora diamantu by sa nemohla použiť na implicitné odvodenie typov pre inštancie, pretože „z dôvodu spätnej kompatibility označuje nová mapa () hrubý typ, a preto ju nemožno použiť pre typ záver." Stránka Type Inference (Všeobecná lekcia) v lekcii Generics lekcie Learning the Java Language trail (Kurz výučby jazyka Java) výučby Java obsahuje časť s názvom „Type Inference and Instantiation of Generic Classes“, ktorá už bola aktualizovaná tak, aby odrážala Java SE 7. Táto časť tiež popisuje, prečo špeciálne musí byť uvedený operátor, ktorý explicitne informuje kompilátor, aby použil inštanciu typu pri inštancii:

Upozorňujeme, že aby ste počas inštancie generickej triedy využili automatické odvodenie typu, musíte určiť operátor kosoštvorca. V nasledujúcom príklade kompilátor generuje nekontrolované upozornenie na prevod, pretože konštruktor HashMap () odkazuje na surový typ HashMap, nie na mapu typu

V položke 24 („Odstránenie nekontrolovaných varovaní“) druhého vydania účinnej Javy Josh Bloch zdôrazňuje v tučne text: „Odstráňte všetky nezaškrtnuté varovania, ktoré môžete.“ Bloch zobrazuje príklad upozornenia na nekontrolovanú konverziu, ktoré sa vyskytne, keď sa na pravej strane deklarácie kompiluje kód, ktorý používa surový typ. Nasledujúci zoznam kódov zobrazuje kód, ktorý povedie k tomuto varovaniu.

záverečná Mapa statesToCities = new HashMap (); // surové! 

Nasledujúce dva snímky obrazovky zobrazujú odpoveď kompilátora na vyššie uvedený riadok kódu. Prvý obrázok zobrazuje správu, keď nie sú povolené žiadne varovania -Xlint, a druhý zobrazuje explicitnejšie varovanie, ktoré sa objaví, keď -Xlint: nezačiarknuté sa poskytuje ako argument pre javac.

Ak Efektívna JavaBloch poukazuje na to, že toto konkrétne nekontrolované varovanie je ľahké vyriešiť explicitným poskytnutím typu parametra na inštanciu generickej triedy. S JDK 7 to bude ešte jednoduchšie! Namiesto toho, aby bolo potrebné pridať explicitný text s týmito názvami typov, je možné typy v mnohých prípadoch odvodiť a špecifikácia diamantového operátora hovorí kompilátoru, aby urobil túto inferenciu, a nie pomocou surového typu.

Nasledujúci zoznam kódov Java poskytuje zjednodušujúce príklady týchto konceptov. Existujú metódy, ktoré demonštrujú inštanciu nespracovanej množiny, inštanciu množiny s explicitnou špecifikáciou jej typu parametra a inštanciu množiny s typom parametra odvodenú z dôvodu špecifikácie diamantového operátora ().

balenie zásypu.príklady; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; importovať statický java.lang.System.out; / ** * Veľmi jednoduchá ukážka „diamantového operátora“ JDK 7 / Project Coin. * / verejná trieda DiamondOperatorDemo {/ ** Použitie typu „raw“. * / private static Set rawWithoutExplicitTyping () {final names set = new HashSet (); addNames (mená); návratové mená; } / ** Explicitne určuje typ inštancie parametra generickej triedy. * / private static Set explicitTypingExplicitlySpecified () {konečné názvy setov = nový HashSet (); addNames (mená); návratové mená; } / ** * Odvodzovanie typu parametra inštancie generickej triedy pomocou nástroja * JDK 7 Diamond Operator. * / private static Set explicitTypingInferredWithDiamond () {konečné názvy setov = nový HashSet (); addNames (mená); návratové mená; } private static void addNames (final Set namesToAddTo) {namesToAddTo.add ("Dustin"); namesToAddTo.add ("Rett"); namesToAddTo.add ("Homer"); } / ** * Hlavná spustiteľná funkcia. * / public static void main (final argumenty String []) {out.println (rawWithoutExplicitTyping ()); out.println (explicitTypingExplicitlySpecified ()); out.println (explicitTypingInferredWithDiamond ()); }} 

Po zostavení vyššie uvedeného kódu vedie k varovaniu iba „surový“ prípad.

V tejto chvíli by mohlo byť rozumné pozrieť sa na to, čo nám hovorí javap o týchto troch metódach. To sa v tomto prípade vykoná príkazom (-v možnosť verbose poskytuje všetky šťavnaté podrobnosti a -p zobrazuje tieto šťavnaté podrobnosti pre súkromné metódy):

javap -v -p -classpath triedy dustin.examples.DiamondOperatorDemo 

Pretože tieto metódy boli všetky v jednej triede, existuje jediný prúd výstupu pre celú triedu. Aby som ich však ľahšie porovnal, výstup som vystrihol a vložil do formátu, ktorý zarovná výstup javapu pre každú metódu proti sebe. Každý stĺpec predstavuje javap výstup pre jednu z metód. Zmenil som farbu písma konkrétnej metódy na modrú, aby vynikla a označila výstup tohto stĺpca.

Okrem názvov samotných metód nie je v javap výkon. Je to tak preto, lebo mazanie generických typov Java znamená, že diferenciácia založená na type nie je za behu k dispozícii. Výukový program Java pre generiká obsahuje stránku nazvanú Vymazanie typu, ktorá to vysvetľuje:

Kompilátor odstráni všetky informácie o argumente skutočného typu v čase kompilácie.

Existuje vymazanie typu, aby mohol nový kód pokračovať v rozhraní so starým kódom. Použitie surového typu z iného dôvodu sa považuje za zlý postup pri programovaní a mali by ste sa mu vyhnúť, kedykoľvek je to možné.

Ako nám pripomína vyššie uvedená citácia, vymazanie znamená, že bajtkód surového typu sa nelíši od explicitne zadaného typu parametra, ale zároveň podporuje vývojárov, aby nepoužívali surové typy okrem integrácie so starým kódom.

Záver

Zahrnutie prevádzkovateľa diamantov () v prostredí Java SE 7 znamená, že kód, ktorý vytvára inštancie generických tried, môže byť menej podrobný. Programovacie jazyky všeobecne a najmä Java smerujú k myšlienkam, ako je konvencia nad konfiguráciou, konfigurácia podľa výnimky, a odvodzovanie vecí tak často, ako je to možné, namiesto toho, aby vyžadovali výslovnú špecifikáciu. Jazyky s dynamickým typom sú dobre známe pre odvodenie typov, ale aj Java so statickým typom toho dokáže viac, ako robí, a príkladom je diamantový operátor.

Originálne uverejnenie príspevku je k dispozícii na //marxsoftware.blogspot.com/

Tento príbeh „JDK 7: The Diamond Operator“ bol pôvodne publikovaný spoločnosťou JavaWorld.

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