Oversikt over Java innebygde merknader

1. Oversikt

I denne artikkelen vil vi snakke om en kjernefunksjon i Java-språket - standardkommentarene som er tilgjengelige i JDK.

2. Hva en kommentar er

Enkelt sagt, kommentarer er det Java-typer som innledes med et “@” -symbol.

Java har hatt merknader helt siden 1.5-utgivelsen. Siden den gang har de formet måten vi har designet applikasjonene våre på.

Spring and Hibernate er gode eksempler på rammer som er sterkt avhengige av merknader for å muliggjøre forskjellige designteknikker.

I utgangspunktet, en kommentar tilordner ekstra metadata til kildekoden den er bundet til. Ved å legge til en kommentar til en metode, grensesnitt, klasse eller felt, kan vi:

  1. Informer kompilatoren om advarsler og feil
  2. Manipuler kildekoden ved kompileringstidspunktet
  3. Endre eller undersøke atferd ved kjøretid

3. Innebygde Java-merknader

Nå som vi har gjennomgått det grunnleggende, la oss ta en titt på noen merknader som leveres med kjernen Java. For det første er det flere som informerer kompilering:

  1. @Overstyring
  2. @SuppressWarnings
  3. @Foreldet
  4. @SafeVarargs
  5. @FunctionalInterface
  6. @Innfødt

Disse kommentarene genererer eller undertrykker kompilatorvarsler og feil. Å bruke dem konsekvent er ofte en god praksis siden å legge dem til kan forhindre fremtidig programmeringsfeil.

De @Overstyring merknader brukes til å indikere at en metode overstyrer eller erstatter oppførselen til en arvet metode.

@SuppressWarnings indikerer at vi vil ignorere visse advarsler fra en del av koden. De @SafeVarargs kommentar virker også på en type advarsel knyttet til bruk av varargs.

De @Foreldet merknader kan brukes til å merke en API som ikke lenger er beregnet for bruk. Videre er denne merknaden ettermontert i Java 9 for å representere mer informasjon om avskrivningen.

For alle disse kan du finne mer detaljert informasjon i artiklene som er lenket.

3.1. @FunctionalInterface

Java 8 lar oss skrive kode på en mer funksjonell måte.

Single Abstract Method-grensesnitt er en stor del av dette. Hvis vi har tenkt at et SAM-grensesnitt skal brukes av lambdas, kan vi eventuelt merke det som sådan med @FunctionalInterface:

@FunctionalInterface public interface Adder {int add (int a, int b); }

Som @Overstyring med metoder, @FunctionalInterface erklærer våre intensjoner med Adder.

Nå, om vi bruker @FunctionalInterface eller ikke, kan vi fortsatt bruke Adder på samme måten:

Adder adder = (a, b) -> a + b; int resultat = adder.add (4,5);

Men hvis vi legger til en annen metode til Adder, så vil kompilatoren klage:

@FunctionalInterface public interface Adder {// compiler klager over at grensesnittet ikke er et SAM int add (int a, int b); int div (int a, int b); }

Dette ville ha samlet uten @FunctionalInterface kommentar. Så hva gir det oss?

Som @Overstyring, denne kommentaren beskytter oss mot fremtidig programmeringsfeil. Selv om det er lovlig å ha mer enn en metode på et grensesnitt, er det ikke når grensesnittet brukes som et lambda-mål. Uten denne kommentaren ville kompilatoren bryte på dusinvis av steder der Adder ble brukt som lambda. Nå, det bare bryter inn Adder seg selv.

3.2. @Innfødt

Fra og med Java 8 er det en ny kommentar i java.lang.annotasjon pakken heter Innfødt. De @Innfødt kommentar gjelder bare felt. Det indikerer at det kommenterte feltet er en konstant som det kan refereres til fra den opprinnelige koden. For eksempel, her er hvordan det brukes i Heltall klasse:

offentlig finaleklasse Heltall {@Native public static final int MIN_VALUE = 0x80000000; // utelatt}

Denne kommentaren kan også tjene som et hint for verktøyene for å generere noen ekstra headerfiler.

4. Meta-merknader

Deretter er metaanmerkninger merknader som kan brukes på andre merknader.

Disse meta-merknadene brukes for eksempel til merknadskonfigurasjon:

  1. @Mål
  2. @Bevaring
  3. @Arvet
  4. @Dokumentert
  5. @Repeatable

4.1. @Mål

Omfanget av merknader kan variere ut fra kravene. Mens en kommentar bare brukes med metoder, kan en annen kommentar forbrukes med konstruktør- og feltdeklarasjoner.

For å bestemme målelementene til en tilpasset kommentar, må vi merke den med a @Mål kommentar.

@Mål kan arbeide med åtte forskjellige elementtyper. Hvis vi ser på kildekoden til @SafeVarargs, så kan vi se at det bare må festes til konstruktører eller metoder:

@Documented @Retention (RetentionPolicy.RUNTIME) @Target ({ElementType.CONSTRUCTOR, ElementType.METHOD}) offentlig @interface SafeVarargs {}

4.2. @Bevaring

Noen merknader er ment å brukes tips til kompilatoren, mens andre brukes under kjøretid.

Vi bruker @Bevaring kommentar for å si hvor i programmets livssyklus vår kommentar gjelder.

For å gjøre dette må vi konfigurere @Bevaring med en av tre retningslinjer for oppbevaring:

  1. RetentionPolicy.SOURCE - synlig for verken kompilatoren eller kjøretiden
  2. RetentionPolicy.CLASS - synlig av kompilatoren
  3. RetentionPolicy.RUNTIME - synlig av kompilatoren og kjøretiden

@Bevaring som standard RetentionPolicy.SOURCE.

Hvis vi har en kommentar som skal være tilgjengelig i løpetid:

@Retention (RetentionPolicy.RUNTIME) @Target (TYPE) offentlig @interface RetentionAnnotation {}

Så hvis vi legger til noen kommentarer til en klasse:

@RetentionAnnotation @Deprecated public class AnnotatedClass {}

Nå kan vi reflektere over Merket klasse for å se hvor mange kommentarer som er beholdt:

@Test offentlig ugyldig nårAnnotationRetentionPolicyRuntime_shouldAccess () {AnnotatedClass anAnnotatedClass = new AnnotatedClass (); Kommentar [] merknader = anAnnotatedClass.getClass (). GetAnnotations (); assertThat (merknader.lengde, er (1)); }

Verdien er 1 pga @RetentionAnnotation har en oppbevaringspolitikk på RUNTIME samtidig som @Foreldet gjør ikke det.

4.3. @Arvet

I noen situasjoner kan det hende vi trenger en underklasse for å få kommentarene bundet til en overordnet klasse.

Vi kan bruke @Arvet kommentar for å få kommentaren til å spre seg fra en kommentert klasse til dens underklasser.

Hvis vi søker @Arvet til vår tilpassede kommentar, og bruk den deretter på BaseClass:

@Inherited @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) public @interface InheritedAnnotation {} @InheritedAnnotation public class BaseClass {} public class DerivedClass utvider BaseClass {}

Så, etter å ha utvidet BaseClass, bør vi se det DerivedClass ser ut til å ha samme kommentar ved kjøretid:

@Test offentlig ugyldig nårAnnotationInherited_thenShouldExist () {DerivedClass derivClass = new DerivedClass (); InheritedAnnotation-kommentar = derivatedClass.getClass () .getAnnotation (InheritedAnnotation.class); assertThat (merknad, forekomst av (InheritedAnnotation.class)); }

Uten @Arvet kommentar, testen ovenfor vil mislykkes.

4.4. @Dokumentert

Som standard dokumenterer ikke Java bruken av en kommentar i Javadocs.

Men vi kan bruke @Dokumentert kommentar for å endre Java sin standard atferd.

Hvis vi lager en tilpasset kommentar som bruker @Dokumentert:

@Documented @Target (ElementType.FIELD) @Retention (RetentionPolicy.RUNTIME) offentlig @interface ExcelCell {int-verdi (); }

Og bruk den på riktig Java-element:

offentlig klasse Ansatt {@ExcelCell (0) offentlig strengnavn; }

Og så Ansatt Javadoc vil avsløre bruk av merknader:

4.5. @Repeatable

Noen ganger kan det være nyttig å spesifisere den samme merknaden mer enn én gang på et gitt Java-element.

Før Java 7 måtte vi gruppere merknader sammen til en enkelt containerkommentar:

@Schedules ({@Schedule (time = "15:05"), @Schedule (time = "23:00")}) ugyldig planningAlarm () {}

Imidlertid brakte Java 7 en renere tilnærming. Med de @Repeatable kommentar, vi kan lage en kommentar som kan repeteres:

@Repeatable (Schedules.class) public @interface Schedule {String time () default "09:00"; }

Å bruke @Repeatable, må vi ha en containerkommentar også. I dette tilfellet vil vi bruke det på nytt @Planer:

public @interface Schedules {Schedule [] value (); }

Selvfølgelig ser dette ut som det vi hadde før Java 7. Men verdien er nå at innpakningen @Planer er ikke spesifisert lenger når vi trenger å gjenta @Rute:

@Schedule @Schedule (time = "15:05") @Schedule (time = "23:00") ugyldig planningAlarm () {}

Fordi Java krever wrapper-kommentaren, var det enkelt for oss å migrere fra pre-Java 7-merkelister til repeterbare kommentarer.

5. Konklusjon

I denne artikkelen har vi snakket om innebygde Java-merknader som alle Java-utviklere bør være kjent med.

Som alltid kan alle eksemplene i artikkelen finnes på GitHub.