Programavimas

„Java 101“: esminių „Java“ kalbos funkcijų apžvalga, 5 dalis

Ankstesnis 1 2 2 puslapis 2 puslapis iš 2

Tipo išvados ir bendrieji konstruktoriai, skirti generinėms ir ne bendrinėms klasėms

Bendrosios ir ne bendrosios klasės gali deklaruoti bendrus konstruktorius, kuriuose konstruktorius turi oficialų tipų parametrų sąrašą. Pvz., Galite deklaruoti šią bendrąją klasę su bendruoju konstruktoriumi:

 viešosios klasės dėžutė {viešoji dėžutė (T t) {// ...}} 

Šioje deklaracijoje nurodoma bendroji klasė Dėžė su formaliu tipo parametru E. Taip pat nurodomas bendras konstruktorius su formalaus tipo parametru T. Galite sugeneruoti bendrąją klasę ir pasikviesti jos konstruktorių taip:

 naujas langelis („Aggies“) 

Ši išraiška sukuria Dėžė, praeina Marmuras į E. Be to, kompiliatorius daro išvadą Stygos kaip Tfaktinio tipo argumentas, nes konstruktoriaus argumentas yra a Stygos objektas.

„Pre-Java 7“ kompiliatoriai daro išvadą, kad bendro konstruktoriaus tipo argumentai yra panašūs į bendro metodo argumentus. Tačiau „Java 7“ kompiliatorius gali padaryti išvadą apie generinių klasių faktinius argumentus, gaunamus deimantų operatoriaus kontekste. Apsvarstykite šį pavyzdį:

 Dėžutės langelis = new Box („Aggies“); 

Taip pat numanyti tipą Marmuras formalaus tipo parametrui E bendrosios klasės Dėžė, kompiliatorius daro išvadą apie tipą Stygos formalaus tipo parametrui T šios generinės klasės konstruktoriaus.

„Project Coin“ mažas pakeitimas Nr. 8: supaprastinta varargų metodo iškvietimas

Prieš „Java 7“ kiekvienas bandymas iškviesti varargą (kintamieji argumentai, dar žinomi kaip kintamas aritas) metodas su nekonfigūruojamu varargų tipu sukėlė kompiliatorių „įspėjimą apie nesaugią operaciją“. Norėdami pašalinti daugelio panašių įspėjamųjų pranešimų (po vieną kiekvienoje skambučio svetainėje) galimybę, „Java 7“ perkėlė įspėjimą iš skambučio vietos į metodo deklaraciją.

Pakartotinai ir pakartotinai neatnaujinami tipai

A pakartotinai atkuriamas tipas vykdymo metu atskleidžia visą informaciją apie tipą. Pavyzdžiai apima primityvius tipus, ne bendrinius tipus, neapdorotus tipus ir nesurištų pakaitinių simbolių iškvietimus. Priešingai, a neatnaujinamas tipas turi kompiliavimo metu pašalintą informaciją apie tipą pagal tipų ištrynimą, kad būtų užtikrintas dvejetainis suderinamumas su „Java“ bibliotekomis ir programomis, kurios buvo sukurtos prieš generinius. Pavyzdžiai: Nustatyti ir Nustatyti. Kadangi nepatvirtinamas tipas nėra visiškai prieinamas vykdymo metu, JVM negali atskirti Nustatyti ir Nustatyti; vykdymo metu, tik neapdorotas tipas Nustatyti yra prieinama.

Tai gali sukelti bendrieji metodai, kurie apima vararg įvesties parametrus krūvos tarša, kuriame parametruojamo tipo kintamasis nurodo objektą, kuris nėra to parametrizuoto tipo (pavyzdžiui, jei neapdorotas tipas buvo sumaišytas su parametruojamu tipu). Kompiliatorius praneša apie „nepatikrintą įspėjimą“, nes negalima patikrinti operacijos, susijusios su parametruojamu tipu (pvz., Perdavimo ar metodo iškvietimo), teisingumo.

13 sąrašas parodo krūvos taršą ne varargų kontekste.

Sąrašas 13. Demonstruoti krūvos taršą ne varargų kontekste

 importuoti java.util.Iterator; importuoti java.util.Set; importuoti java.util.TreeSet; public class HeapPollutionDemo {public static void main (String [] args) {Set s = new TreeSet (); Nustatykite ss = s; // nepatikrintas įspėjimas s.add (naujas sveikasis skaičius (42)); // kitas nepatikrintas įspėjimas Iterator iter = ss.iterator (); while (iter.hasNext ()) {String str = iter.next (); // „ClassCastException“ metama sistema.out.println (str); }}} 

Kintamas ss turi parametruojamą tipą Nustatyti. Kai java.util.Rinkinys kad nurodė s yra priskirtas ss, kompiliatorius generuoja nepatikrintą įspėjimą. Tai daro todėl, kad kompiliatorius negali to nustatyti s reiškia a Nustatyti tipas (jis nėra). Rezultatas - krūvos tarša. (Kompiliatorius leidžia šiai užduočiai išsaugoti atgalinį suderinamumą su senomis „Java“ versijomis, kurios nepalaiko generinių. Be to, tipo ištrynimo transformacijos Nustatyti į Nustatyti, kurio rezultatas yra vienas Nustatyti skiriamas kitam Nustatyti.)

Kompiliatorius sukuria antrą nepatikrintą įspėjimą eilutėje, kuri iškviečia Nustatyti's papildyti() metodas. Tai daro todėl, kad negali nustatyti, ar kintamasis s reiškia a Nustatyti arba Nustatyti tipo. Tai dar viena su kaupu susijusi taršos situacija. (Kompiliatorius leidžia šiam metodui iškviesti, nes ištrynimas transformuojasi Nustatyti's loginis pridėjimas (E e) metodas loginis pridėjimas (o objektas), kuris gali pridėti bet kokį objektą prie rinkinio, įskaitant java.lang.Integer potipis java.lang.Object.)

Krūvos tarša gali lengvai atsirasti varargų kontekste. Pavyzdžiui, apsvarstykite 14 sąrašą.

Sąrašas 14. Krūvos taršos demonstravimas varargų kontekste

 importuoti java.util.Arrays; importuoti java.util.List; public class UnsafeVarargsDemo {public static void main (String [] args) {unsafe (Arrays.asList ("A", "B", "C"), Arrays.asList ("D", "E", "F") ); } static void unsafe (sąrašas ... l) {objektas [] oArray = l; oArray [0] = Arrays.asList (naujas dvigubas (3.5)); Eilutė s = l [0] .get (0); }} 

Objektas [] oArray = l; užduotis suteikia galimybę kaupti krūvą. Vertė, neatitinkanti parametruojamo parametro „varargs“ tipo l galima priskirti kintamajam oArray. Tačiau kompiliatorius nesukuria nepažymėto įspėjimo, nes jis tai jau padarė verdamas Sąrašas ... l į Sąrašas [] l. Ši užduotis galioja, nes kintamasis l turi tipą Sąrašas [], kurie potipiai Objektas [].

Be to, kompiliatorius neskiria įspėjimo ar klaidos priskirdamas Sąrašas bet kokio tipo objektas bet kuriam iš oArraymasyvo komponentai; pavyzdžiui, oArray [0] = Arrays.asList (naujas dvigubas (3.5));. Šis priskyrimas priskiriamas pirmajam masyvo komponentui oArray a Sąrašas objektas, kuriame yra vienas java.lang.Dvigubai objektas.

Eilutė s = l [0] .get (0); užduotis yra problemiška. Objektas, saugomas kintamojo pirmame masyvo komponente l turi tipą Sąrašas, bet ši užduotis tikisi tipo objekto Sąrašas. Dėl to JVM meta java.lang.ClassCastException.

Sudarykite šį šaltinio kodą (javac -Xlint: nepažymėta „UnsafeVarargsDemo.java“). Turėtumėte stebėti šią išvestį (šiek tiek performatuotą, kad būtų lengviau skaityti) sudarant „Java SE 7“ 6 naujinimą:

 UnsafeVarargsDemo.java:8: įspėjimas: [nepažymėtas] nepažymėtas bendrojo masyvo kūrimas parametrų „Varargs“ tipui, kurio tipas yra sąrašas [] nesaugus (Arrays.asList ("A", "B", "C"), ^ UnsafeVarargsDemo.java:12: įspėjimas : [nepatikrinta] Galima krūvos tarša dėl parametruojamo vararg tipo Sąrašo statinis negaliojantis nesaugus (sąrašas ... l) ^ 2 įspėjimai 

Savo „Java 101“ įvade į generikus nurodžiau, kad masyvo kūrimo išraiškose negalima naudoti tipo parametrų. Pavyzdžiui, negalite nurodyti elementai = naujas E [dydis];. Kompiliatorius praneša apie „bendros masyvo kūrimo klaidos“ pranešimą, kai bandote tai padaryti. Tačiau vis tiek įmanoma sukurti bendrą masyvą, bet tik varargo kontekste, ir tai yra pirmasis įspėjamasis pranešimas. Užkulisiuose kompiliatorius transformuojasi Sąrašas ... l į Sąrašas [] l o paskui į Sąrašas [] l.

Atkreipkite dėmesį, kad įspėjimas apie taršos kaupimąsi yra sukurtas nesaugus () metodo deklaravimo svetainė. Šis pranešimas nėra sugeneruotas šio metodo skambučių svetainėje, kaip yra „Java 5“ ir „6“ kompiliatoriuose.

Ne visi varargų metodai prisidės prie krūvos taršos. Tačiau metodo deklaravimo vietoje vis tiek bus išsiųstas įspėjamasis pranešimas. Jei žinote, kad jūsų metodas neprisideda prie taršos kaupimo, galite nuslopinti šį įspėjimą paskelbdami jį @SafeVarargs anotacija - „Java 7“ pristatė java.lang.SafeVarargs anotacijos tipas. Pavyzdžiui, dėl to, kad nėra galimybės Masyvai klasės asList () prisidėti prie krūvos taršos, šio metodo deklaracija buvo pažymėta @SafeVarargs, taip:

 @SafeVarargs viešasis statinis sąrašas kaip sąrašas (T ... a) 

@SafeVarargs anotacija pašalina bendro masyvo kūrimą ir įspėjimus apie kaupą. Tai dokumentais pagrįsta metodo sutarties dalis ir tvirtina, kad metodo įgyvendinimas netinkamai neapdoros oficialaus „Varargs“ parametro.

Apibendrinant

„Java 7“ pagerino kūrėjų produktyvumą įdiegdama automatinį išteklių valdymą naudodama „try-with-resources“ pareiškimą ir naują Automatiškai uždaromas sąsaja, įjungta eilutė, daugialypis ryšys, galutinis permetimas, dvejetainiai litraalai, pabraukimai skaitmeniniuose litraaluose, kompiliatoriaus tipo išvadų algoritmo, įvedusio vadinamąjį deimantinį operatorių, pakeitimai ir supaprastintas varargų metodo iškvietimas. Toliau „Java 101“: nauja karta serija yra žvilgsnis į „Java 8“ lambda ir funkcinės sąsajos kalbos ypatybes.

Šią istoriją „Java 101: esminių„ Java “kalbos funkcijų apžvalga, 5 dalis“ iš pradžių paskelbė „JavaWorld“.