Programavimas

JDK 7: Deimantų operatorius

„Project Coin“ pateikia daugybę „mažų kalbos patobulinimų“ kaip naujų JDK 7 funkcijų pogrupį. Neseniai rašiau tinklaraštį apie „Project Coin“ įjungimą „Strings“ ir šiame įraše rašau apie naująjį „Diamond Operator“ ().

„Diamond Operator“ sumažina kai kuriuos „Java“ paprastus žodžius, susijusius su generiniais vaistais, nes kompiliatorius daro išvadą apie parametrų tipus bendrųjų klasių konstruktoriams. Pirminis pasiūlymas įtraukti „Diamond Operator“ į „Java“ kalbą buvo pateiktas 2009 m. Vasario mėn. Ir apima šį paprastą pavyzdį:

Pvz., Apsvarstykite šį priskyrimo sakinį:

Žemėlapis anagrams = new HashMap();

Tai gana ilga, todėl ją galima pakeisti taip:

Žemėlapis anagramos = naujas „HashMap“ ();

Pirmiau pateiktas Jeremy Mansono pasiūlyme pateiktas pavyzdys (kuris buvo vienas pirmųjų atsakant į kvietimą pateikti „Project Coin“ idėjas) yra paprastas, tačiau tinkamai parodo, kaip „Diamond Operator“ yra taikomas JDK 7. Mansono pasiūlyme taip pat pateikiama reikšminga priežastis, kodėl šis papildymas buvo pageidautina:

Reikalavimas, kad tipo parametrai būtų dubliuojami be reikalo

tai skatina nelaimingą

statinių gamyklinių metodų gausa vien dėl tipo išvados

dirba prie metodų iškvietimų.

Kitaip tariant, „JDK 7“ projekto moneta pridėjus deimantinį operatorių, daro konstruktoriams išvadą, kuri buvo prieinama taikant metodus. Naudojant metodus, netiesiogiai daroma išvada, kai paliekama aiški parametro tipo specifikacija. Kita vertus, deimantų operatorius turi būti aiškiai nurodytas, kad kompiliatorius „nurodytų“ padaryti išvadą apie tipą.

Savo pradiniame pasiūlyme Mansonas nurodo, kad sintaksė be specialaus deimanto operatoriaus negalėjo būti naudojama netiesiogiai darant išvadas apie pavyzdžių tipus, nes „atgalinio suderinamumo tikslais naujasis žemėlapis () nurodo neapdorotą tipą, todėl jo negalima naudoti tipui išvadą “. „Java“ pamokų „Java“ kalbos tako mokymosi „Generics Lesson“ puslapyje „Tipo išvada“ yra skyrius, pavadintas „Tipo išvada ir bendrųjų klasių kūrimas“, kuris jau buvo atnaujintas, kad atspindėtų „Java SE 7“. Šiame skyriuje taip pat aprašoma, kodėl turi būti nurodytas operatorius, kuris aiškiai informavo kompiliatorių, kad jis naudotų tipo išvadas atliekant momentinius veiksmus:

Atkreipkite dėmesį, kad norint pasinaudoti automatinio tipo išvadomis, atliekant bendros klasės pavyzdį, turite nurodyti deimantų operatorių. Šiame pavyzdyje kompiliatorius generuoja nepatvirtintą konversijos įspėjimą, nes „HashMap“ () konstruktorius nurodo „HashMap“ neapdorotą tipą, o ne žemėlapį tipo

„Efektyvios„ Java “antrojo leidimo 24 punkte („ Pašalinkite nepažymėtus įspėjimus “) Joshas Blochas pabrėžia drąsus tekstas: „Pašalinkite kiekvieną nepažymėtą įspėjimą“. „Bloch“ rodo nepatvirtinto konversijos įspėjimo pavyzdį, kuris atsiranda, kai kompiliuojamas kodas, kuris naudoja neapdorotą tipą dešinėje deklaracijos pusėje. Kitame kodų sąraše rodomas kodas, kuris paskatins šį įspėjimą.

galutinis žemėlapis statesToCities = naujas HashMap (); // žalias! 

Kiti du ekrano momentiniai vaizdai rodo kompiliatoriaus atsakymą į pirmiau nurodytą kodo eilutę. Pirmajame paveikslėlyje rodomas pranešimas, kai nėra įjungtų įspėjimų -Xlint, o antrame - aiškesnis įspėjimas, atsirandantis, kai -Xlint: nepatikrinta yra pateiktas kaip argumentas „javac“.

Jei Veiksminga „Java“, Blochas pabrėžia, kad šį konkretų nepatikrintą įspėjimą lengva išspręsti aiškiai nurodant parametro tipą bendrosios klasės pavyzdžiui. Su JDK 7 tai bus dar lengviau! Užuot reikėję pridėti aiškų tekstą su šių tipų pavadinimais, tipus galima padaryti daugeliu atvejų, o deimantų operatoriaus specifikacija nurodo kompiliatoriui padaryti šią išvadą, o ne naudoti neapdorotą tipą.

Kitame „Java“ kodų sąraše pateikiami supaprastinti šių sąvokų pavyzdžiai. Yra metodų, kurie parodo neapdoroto rinkinio egzempliorių, aibės egzempliorių, aiškiai nurodant jo parametrų tipą, ir aibės egzempliorių su parametro tipu, dėl kurių galima spręsti dėl deimantų operatoriaus specifikacijos ().

pakuotė dustin.pavyzdžiai; importuoti java.util.HashMap; importuoti java.util.HashSet; importuoti java.util.Žemėlapis; importuoti java.util.Set; importuoti statinį java.lang.System.out; / ** * Labai paprastas JDK 7 / „Project Coin“ „Deimantinio operatoriaus“ demonstravimas. * / viešoji „DiamondOperatorDemo“ klasė {/ ** „raw“ tipo naudojimas. * / private static Set rawWithoutExplicitTyping () {final Set names = new HashSet (); addNames (vardai); grąžinti vardus; } / ** Aiškiai nurodant bendrosios klasės pavyzdžio parametrų tipą. * / private static Set explicitTypingExplicitlySpecified () {final Set names = new HashSet (); addNames (vardai); grąžinti vardus; } / ** * „JDK 7“ * „Diamond Operator“ daroma išvada apie bendros klasės pavyzdžio parametrų tipą. * / private static Set explicitTypingInferredWithDiamond () {final Set names = new HashSet (); addNames (vardai); grąžinti vardus; } private static void addNames (galutiniai rinkinio vardaiToAddTo) {vardaiToAddTo.add ("Dustin"); vardaiToAddTo.add ("Rett"); vardaiToAddTo.add („Homeras“); } / ** * Pagrindinė vykdomoji funkcija. * / public static void main (paskutiniai eilutės [] argumentai) {out.println (rawWithoutExplicitTyping ()); out.println (explicitTypingExplicitlySpecified ()); out.println (explicitTypingInferredWithDiamond ()); }} 

Sudarant aukščiau pateiktą kodą, tik „neapdorotas“ atvejis sukelia įspėjimą.

Šiuo metu gali būti įžvalgu pažvelgti į tai, ką „javap“ mums pasakoja apie šiuos tris metodus. Šiuo atveju tai daroma su komanda (-v variantas žodžiu pateikia visas sultingas detales ir -p rodo šias sultingas detales privatus metodai):

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

Kadangi visi šie metodai buvo vienoje klasėje, visos klasės srautas yra vienas. Tačiau, kad būtų lengviau juos palyginti, sukarpiau išvestį į formatą, kuris sulygina kiekvieno metodo javap išvestį. Kiekvienas stulpelis žymi javap vieno iš metodų išvestis. Pakeičiau konkretaus metodo šrifto spalvą į mėlyną, kad ji taptų ryški ir pažymėčiau tos stulpelio išvestį.

Išskyrus pačių metodų pavadinimus, NĖRA jokio skirtumo javap produkcija. Taip yra todėl, kad „Java“ generinių tipų ištrynimas reiškia, kad diferencijavimas pagal tipą nėra vykdymo metu. „Java“ pamokoje apie „Generics“ yra puslapis, pavadintas „Type Erasure“, kuris paaiškina tai:

Kompiliatorius kompiliavimo metu pašalina visą informaciją apie tikrojo tipo argumentą.

Tipas ištrinamas, kad naujas kodas galėtų ir toliau sąveikauti su senu kodu. Neapdoroto tipo naudojimas dėl bet kokios kitos priežasties laikomas bloga programavimo praktika, todėl jo reikėtų vengti, kai tik įmanoma.

Kaip mums primena aukščiau pateikta citata, ištrynimas reiškia, kad neapdoroto tipo baitas koduoti nesiskiria nuo aiškiai įvesto parametro tipo, tačiau taip pat skatina kūrėjus nenaudoti neapdorotų tipų, išskyrus integravimą su senu kodu.

Išvada

Deimantų operatoriaus įtraukimas () „Java SE 7“ reiškia, kad kodas, kuris sukuria bendrąsias klases, gali būti ne toks išsamus. Kodavimo kalbos apskritai ir ypač „Java“ juda link tokių idėjų, kaip susitarimo dėl konfigūracijos, konfigūracijos išimties tvarka ir kuo dažniau išvadų, o ne reikalaujančios aiškaus aprašymo. Dinamiškai įvestos kalbos yra gerai žinomos dėl tipo išvadų, tačiau net ir statinio tipo „Java“ gali tai padaryti daugiau nei daro, o deimantų operatorius yra to pavyzdys.

Originalų skelbimą galima rasti adresu //marxsoftware.blogspot.com/

Šią istoriją „JDK 7: Deimantinis operatorius“ iš pradžių išleido „JavaWorld“.