Project Coin giver adskillige "små sprogforbedringer" som en delmængde af de nye JDK 7-funktioner. Jeg bloggede for nylig på Project Coin, der tænder for strenge, og i dette indlæg skriver jeg om den nye Diamond Operator ().
Diamond Operator reducerer noget af Javas bredhed omkring generiske gener ved at lade kompilatoren udlede parametertyper til konstruktører af generiske klasser. Det oprindelige forslag om at tilføje Diamond Operator til Java-sproget blev fremsat i februar 2009 og inkluderer dette enkle eksempel:
Overvej f.eks. Følgende opgaveerklæring:
Kort Dette er ret langvarigt, så det kan erstattes med dette: Kort Ovenstående eksempel givet i Jeremy Mansons forslag (som var et af de første som svar på en opfordring til Project Coin-ideer) er simpelt, men viser tilstrækkeligt, hvordan diamantoperatøren anvendes i JDK 7. Mansons forslag giver også væsentlig betydning for, hvorfor denne tilføjelse var ønskeligt: Kravet om, at typeparametre duplikeres unødigt som dette tilskynder en ulykkelig overvægt af statiske fabriksmetoder, simpelthen fordi type inferens arbejder på metodeopkald. Med andre ord, JDK 7 Project Coin-tilføjelsen af en diamantoperatør bringer typeforhold til konstruktører, der har været tilgængelige med metoder. Med metoder udføres typeafledning implicit, når man forlader den eksplicitte parametertypespecifikation. Med instantiering skal derimod diamantoperatøren specificeres eksplicit for at "fortælle" kompilatoren at udlede typen. I sit oprindelige forslag påpeger Manson, at syntaks uden en speciel diamantoperatør ikke kunne bruges til implicit at udlede typer til instantieringer, fordi "med henblik på bagudkompatibilitet angiver nyt kort () en rå type og derfor ikke kan bruges til type slutning. " Siden Type Inference i Generics Lesson of the Learning the Java Language trail i Java Tutorials inkluderer et afsnit kaldet "Type Inference and Instantiation of Generic Classes", der allerede er blevet opdateret til at afspejle Java SE 7. Dette afsnit beskriver også hvorfor specialet operatør skal specificeres for eksplicit at informere kompilatoren om at bruge typeinferens ved instantiering: I punkt 24 ("Eliminer ukontrollerede advarsler") i anden udgave af effektiv Java understreger Josh Bloch i fremhævet tekst, "Fjern enhver ukontrolleret advarsel, du kan." Bloch viser et eksempel på den ukontrollerede konverteringsadvarsel, der opstår, når man kompilerer kode, der bruger en rå type på højre side af en erklæring. Den næste kodeliste viser kode, der vil føre til denne advarsel. De næste to skærmbilleder viser kompilatorens svar på ovenstående kodelinje. Det første billede viser beskeden, når der ikke er aktiveret -Xlint-advarsler, og det andet viser den mere eksplicitte advarsel, der opstår når Hvis Effektiv Java, Bloch påpeger, at denne særlige ukontrollerede advarsel er let at adressere ved eksplicit at angive parametertypen til instantiering af den generiske klasse. Med JDK 7 bliver dette endnu lettere! I stedet for at skulle tilføje den eksplicitte tekst med disse typenavne, kan typerne udledes i mange tilfælde, og specifikationen af diamantoperatøren fortæller kompilatoren at foretage denne slutning i stedet for at bruge den rå type. Den næste Java-kodeliste giver forenklede eksempler på disse begreber. Der er metoder, der demonstrerer instantiering af et råt sæt, instantiering af et sæt med eksplicit specifikation af dets parametertype og instantiering af et sæt med afledt parametertype på grund af specifikation af diamantoperatøren ( Når ovenstående kode er kompileret, er det kun den "rå" sag, der fører til en advarsel. På dette tidspunkt kan det være indsigtsfuldt at se på, hvad javap fortæller os om disse tre metoder. Dette gøres i dette tilfælde med kommandoen ( Fordi disse metoder alle var i en enkelt klasse, er der en enkelt strøm af output for hele klassen. For at gøre det lettere at sammenligne dem har jeg dog klippet og indsat output i et format, der justerer javap-output for hver metode mod hinanden. Hver kolonne repræsenterer Bortset fra navnene på selve metoderne er der INGEN forskel i Compileren fjerner alle oplysninger om det aktuelle typeargument på kompileringstidspunktet. Type sletning findes, så ny kode kan fortsætte med at grænseflade med ældre kode. Brug af en rå type af anden grund betragtes som dårlig programmeringspraksis og bør undgås, når det er muligt. Som citatet ovenfor minder os om, betyder sletning, at at bytekode en rå type ikke er anderledes end en eksplicit indtastet parametertype, men også tilskynder udviklere til ikke at bruge rå typer undtagen at integrere med ældre kode. Konklusion Inkluderingen af diamantoperatøren ( Oprindelig udstationering tilgængelig på //marxsoftware.blogspot.com/ Denne historie, "JDK 7: The Diamond Operator" blev oprindeligt udgivet af JavaWorld.endelige kort
-Xlint: ikke markeret
leveres som et argument til javac.).
pakke dustin. eksempler; importere java.util.HashMap; importere java.util.HashSet; importere java.util.Map; importere java.util.Set; importere statisk java.lang.System.out; / ** * Meget enkel demonstration af JDK 7's / Project Coin's "Diamond Operator." * / public class DiamondOperatorDemo {/ ** Brug af "rå" type. * / privat statisk sæt rawWithoutExplicitTyping () {final Set names = new HashSet (); addNames (navne); returnere navne; } / ** Angiver eksplicit generisk klasses instantieringsparametertype. * / privat statisk sæt explicitTypingExplicitlySpecified () {final Set names = new HashSet (); addNames (navne); returnere navne; } / ** * Udleder generisk klasses instantieringsparametertype med JDK 7's * 'Diamond Operator.' * / private static Set explicitTypingInferredWithDiamond () {final Set names = new HashSet (); addNames (navne); returnere navne; } private statiske ugyldige addNames (final Set namesToAddTo) {namesToAddTo.add ("Dustin"); namesToAddTo.add ("Rett"); namesToAddTo.add ("Homer"); } / ** * Hovedfunktionsfunktion. * / public static void main (final String [] argumenter) {out.println (rawWithoutExplicitTyping ()); out.println (explicitTypingExplicitlySpecified ()); out.println (explicitTypingInferredWithDiamond ()); }}
-v
mulighed for verbose giver alle de saftige detaljer og -p
viser disse saftige detaljer til privat
metoder):javap -v -p -classpath klasser dustin.examples.DiamondOperatorDemo
javap
output til en af metoderne. Jeg har ændret skrifttypefarven på den bestemte metode til blå for at få den til at skille sig ud og mærke kolonnens output.javap
produktion. Dette skyldes, at Java generics type sletning betyder, at differentiering baseret på type ikke er tilgængelig under kørsel. Java-vejledningen om generik inkluderer en side kaldet Type Erasure, der forklarer dette:) i Java SE 7 betyder, at kode, der instanterer generiske klasser, kan være mindre detaljeret. Kodningssprog generelt og Java i særdeleshed bevæger sig mod ideer som konvention over konfiguration, konfiguration undtagelsesvis og udleder ting så ofte som muligt i stedet for at kræve eksplicit specifikation. Dynamisk typede sprog er velkendte for typeinferens, men selv statisk typet Java kan gøre mere af dette end det gør, og diamantoperatøren er et eksempel på dette.