Programmēšana

Java 101: būtiskās Java valodas iespējas, 5. daļa

Iepriekšējā 1 2 2. lapa 2. lapa no 2

Tipa secinājums un vispārīgie konstruktori vispārīgām un ne-vispārīgām klasēm

Vispārējās un neģeneriskās klases var deklarēt vispārīgus konstruktorus, kuros konstruktoram ir formāls tipu parametru saraksts. Piemēram, jūs varētu deklarēt šādu vispārīgo klasi ar vispārēju konstruktoru:

 public class Box {public Box (T t) {// ...}} 

Šī deklarācija norāda vispārīgo klasi Kaste ar formāla tipa parametru E. Tas arī norāda vispārēju konstruktoru ar formāla tipa parametru T. Jūs varētu noteikt vispārīgo klasi un izsaukt tās konstruktoru šādi:

 jauns lodziņš ("Aggies") 

Šis izteiciens rada Kaste, garāmejot Marmors uz E. Arī sastādītājs secina StīgaTfaktiskā tipa arguments, jo konstruktora arguments ir a Stīga objekts.

Pre-Java 7 sastādītāji secina vispārīga konstruktora faktiskā tipa argumentus līdzīgi kā vispārīgās metodes argumenti. Tomēr Java 7 kompilators var secināt, ka dimantu operatora kontekstā tiek parādīti vispārīgās klases faktiskie argumenti. Apsveriet šādu piemēru:

 Box box = new Box ("Aggies"); 

Kā arī secināt veidu Marmors formālā tipa parametram E no vispārējās klases Kaste, sastādītājs secina veidu Stīga formālā tipa parametram T šīs vispārīgās klases konstruktora.

Projekta Coin mazās izmaiņas # 8: Vienkāršota Varargs metodes izsaukšana

Pirms Java 7 katrs mēģinājums izsaukt varargs (mainīgie argumenti, kas pazīstami arī kā mainīga aritāte) metode ar neatkārtojamu varargs tipu lika kompilatoram izdot brīdinājumu "nedroša darbība". Lai novērstu daudzu līdzīgu brīdinājuma ziņojumu iespējamību (viens katrā zvana vietnē), Java 7 pārvietoja brīdinājumu no zvana vietnes uz metodes deklarāciju.

Atkārtojami un neatkārtojami veidi

A atkārtoti pārbaudāms tips izpildes laikā atklāj pilnīgu informāciju par tipu. Piemēri ietver primitīvos veidus, vispārīgos veidus, neapstrādātos veidus un nesaistīto aizstājējzīmju izsaukumus. Turpretī a neatkārtojams tips ir apkopota laikā noņemta informācija par tipu pēc veida dzēšanas, lai nodrošinātu bināro savietojamību ar Java bibliotēkām un lietojumprogrammām, kas tika izveidotas pirms vispārīgajām. Piemēri ietver Iestatiet un Iestatiet. Tā kā neatkārtojams tips izpildes laikā nav pilnībā pieejams, JVM nevar atšķirt Iestatiet un Iestatiet; izpildlaika laikā tikai neapstrādāts veids Iestatiet ir pieejams.

Var izraisīt vispārīgas metodes, kas ietver vararg ievades parametrus kaudzes piesārņojums, kurā parametrizēta tipa mainīgais attiecas uz objektu, kas nav šī parametrizētā tipa (piemēram, ja neapstrādāts tips ir sajaukts ar parametrizētu tipu). Sastādītājs ziņo par "nepārbaudītu brīdinājumu", jo nevar pārbaudīt darbības pareizību, kas saistīta ar parametrizētu tipu (piemēram, cast vai method izsaukumu).

13. saraksts parāda kaudzes piesārņojumu ne-varargs kontekstā.

Uzskaitījums 13. Kaudzes piesārņojuma demonstrēšana ne-varargs kontekstā

 importēt java.util.Iterator; importēt java.util.Set; importēt java.util.TreeSet; public class HeapPollutionDemo {public static void main (String [] args) {Set s = new TreeSet (); Iestatiet ss = s; // nepārbaudīts brīdinājums s.add (new Integer (42)); // vēl viens nepārbaudīts brīdinājums Iterator iter = ss.iterator (); while (iter.hasNext ()) {String str = iter.next (); // ClassCastException izmet System.out.println (str); }}} 

Mainīgs ss ir parametru tips Iestatiet. Kad java.util.Set uz kuru atsaucas s tiek piešķirts ss, sastādītājs ģenerē nepārbaudītu brīdinājumu. Tas tiek darīts, jo kompilators to nevar noteikt s attiecas uz a Iestatiet tips (tā nav). Rezultāts ir kaudzes piesārņojums. (Kompilators ļauj šim uzdevumam saglabāt savietojamību ar mantotajām Java versijām, kas neatbalsta vispārīgās. Turklāt tipu dzēšanas transformācijas Iestatiet vērā Iestatiet, kā rezultātā rodas viens Iestatiet tiek piešķirts citam Iestatiet.)

Sastādītājs ģenerē otru nepārbaudītu brīdinājumu uz līnijas, kas izsauc Iestatiet's pievienot () metodi. Tas tiek darīts, jo nevar noteikt, vai mainīgais s attiecas uz a Iestatiet vai Iestatiet tips. Šī ir vēl viena kaudzes piesārņojuma situācija. (Kompilators atļauj izsaukt šo metodi, jo dzēšana pārveidojas Iestatiet's Būla pievienojums (E e) metodi būla pievienošana (objekts o), kas kopai var pievienot jebkura veida objektus, ieskaitot java.lang.Integer apakštips java.lang.Object.)

Kaudzes piesārņojums var viegli rasties vararga apstākļos. Piemēram, apsveriet 14. sarakstu.

Uzskaitījums 14. Kaudzes piesārņojuma parādīšana varargu kontekstā

 importēt java.util.Arrays; importēt java.util.List; public class UnsafeVarargsDemo {public static void main (String [] args) {nedrošs (Arrays.asList ("A", "B", "C"), Arrays.asList ("D", "E", "F") ); } static void nedrošs (saraksts ... l) {objekts [] oArray = l; oArray [0] = Arrays.asList (jauns Double (3.5)); Virkne s = l [0] .get (0); }} 

The Objekts [] oArray = l; uzdevums ievieš kaudzes piesārņojuma iespēju. Vērtība, kas neatbilst parametra varargs parametram l var piešķirt mainīgajam oAray. Tomēr kompilators nerada nepārbaudītu brīdinājumu, jo tas jau ir izdarīts, tulkojot Saraksts ... l uz Saraksts [] l. Šis uzdevums ir derīgs, jo mainīgais l ir tips Saraksts [], kuri apakštipi Objekts [].

Piešķirot a, sastādītājs neizdod brīdinājumu vai kļūdu Saraksts jebkura veida objekts jebkuram no oAraymasīva komponenti; piemēram, oArray [0] = Arrays.asList (jauns Double (3.5));. Šis uzdevums tiek piešķirts pirmajam masīva komponentam oAray a Saraksts objekts, kas satur vienu java.lang.Dubulta objekts.

The Virkne s = l [0] .get (0); uzdevums ir problemātisks. Objekts, kas saglabāts mainīgā pirmajā masīva komponentā l ir tips Saraksts, bet šis uzdevums sagaida tipa objektu Saraksts. Rezultātā JVM iemet java.lang.ClassCastException.

Apkopojiet šo avota kodu (javac -Xlint: neatzīmēts UnsafeVarargsDemo.java). Sastādot ar Java SE 7 6. atjauninājumu, jums jāievēro šāda (nedaudz pārformatēta lasāmībai) izeja:

 UnsafeVarargsDemo.java:8: brīdinājums: [nepārbaudīts] nav pārbaudīts vispārēja masīva izveide parametra Varargs tipam List [] nedrošs (Arrays.asList ("A", "B", "C"), ^ UnsafeVarargsDemo.java:12: brīdinājums : [nav pārbaudīts] Iespējamais kaudzes piesārņojums, ko rada parametru Vararg tips List static void unsafe (List ... l) ^ 2 brīdinājumi 

Savā Java 101 ievadā par vispārīgajiem apgalvoju, ka masīva izveides izteiksmēs nevar izmantot tipa parametrus. Piemēram, jūs nevarat norādīt elementi = jauns E [izmērs];. Kad mēģināt to izdarīt, kompilators ziņo par ziņojumu “vispārīga masīva izveides kļūda”. Tomēr joprojām ir iespējams izveidot vispārīgu masīvu, bet tikai varargs kontekstā, un par to ziņo pirmais brīdinājuma ziņojums. Aizkulisēs sastādītājs pārveidojas Saraksts ... l uz Saraksts [] l un pēc tam uz Saraksts [] l.

Ievērojiet, ka brīdinājums par kaudzes piesārņojumu tiek radīts nedrošs () metodes deklarēšanas vietne. Šis ziņojums netiek ģenerēts šīs metodes zvana vietnē, piemēram, Java 5 un 6 kompilatoros.

Ne visas vararga metodes veicinās kaudzes piesārņošanu. Tomēr brīdinājuma ziņojums joprojām tiks izsniegts metodes deklarēšanas vietā. Ja jūs zināt, ka jūsu metode neveicina kaudzes piesārņošanu, varat nomākt šo brīdinājumu, paziņojot to ar @SafeVarargs anotācija - Java 7 ieviesa java.lang.SafeVarargs anotācijas veids. Piemēram, tāpēc, ka tam nav iespējas Masīvi klases asList () kaudzes piesārņojuma veicināšanai, šīs metodes deklarācija ir anotēta @SafeVarargs, sekojoši:

 @SafeVarargs publiskais statiskais saraksts asList (T ... a) 

The @SafeVarargs anotācija novērš vispārēju masīvu izveides un kaudzes piesārņojuma brīdinājuma ziņojumus. Tā ir dokumentēta metodes līguma daļa un apgalvo, ka metodes ieviešana nepareizi apstrādās formālo parametru Varargs.

Noslēgumā

Java 7 uzlaboja izstrādātāju produktivitāti, ieviešot automātisku resursu pārvaldību, izmantojot paziņojumu “mēģiniet ar resursiem”, kā arī jaunu Automātiski aizverams saskarne, ieslēgšana virknē, daudzu nozveju, gala atkārtošana, binārie literāļi, pasvītrojumi skaitliskajos literālos, izmaiņas sastādītāja tipa secinājuma algoritmā, ar kuru tika ieviests tā sauktais dimanta operators, un vienkāršota vararga metodes izsaukšana. Nākamais Java 101: nākamā paaudze sērija ir ieskats Java 8 lambda un funkcionālās saskarnes valodas funkcijās.

Šo stāstu "Java 101: Būtisko Java valodas funkciju ceļvedis, 5. daļa" sākotnēji publicēja JavaWorld.