Programmering

Sådan beskrives Java-kode med kommentarer

Du har sandsynligvis stødt på situationer, hvor du har brug for at associere metadata (data, der beskriver andre data) med klasser, metoder og / eller andre applikationselementer. For eksempel kan dit programmeringsteam muligvis have brug for at identificere ufærdige klasser i en stor applikation. For hver ufærdig klasse vil metadataene sandsynligvis indeholde navnet på den udvikler, der er ansvarlig for at afslutte klassen, og klassens forventede afslutningsdato.

Før Java 5 var kommentarer den eneste fleksible mekanisme, som Java havde at tilbyde for at knytte metadata til applikationselementer. Kommentarer er dog et dårligt valg. Da compileren ignorerer dem, er kommentarer ikke tilgængelige under kørsel. Og selvom de var tilgængelige, skulle teksten analyseres for at opnå vigtige dataelementer. Uden at standardisere, hvordan dataelementerne er specificeret, kan disse dataelementer vise sig umulige at parse.

download Hent koden Download kildekoden for eksempler i denne Java 101-tutorial. Oprettet af Jeff Friesen til.

Ikke-standardiserede annoteringsmekanismer

Java giver ikke-standardiserede mekanismer til at forbinde metadata med applikationselementer. F.eks forbigående reserveret ord lader dig kommentere (knytte data til) felter, der skal udelukkes under serialisering.

Java 5 ændrede alt ved at introducere kommentarer, en standardmekanisme til at forbinde metadata med forskellige applikationselementer. Denne mekanisme består af fire komponenter:

  • En @interface mekanisme til at erklære annoteringstyper.
  • Meta-annotationstyper, som du kan bruge til at identificere de applikationselementer, som en annotationstype gælder for; at identificere levetiden for en kommentar (en forekomst af en annoteringstype); og mere.
  • Understøttelse af annoteringsbehandling via en udvidelse til Java Reflection API (diskuteres i en fremtidig artikel), som du kan bruge til at opdage et programs runtime-annoteringer og et generaliseret værktøj til behandling af annoteringer.
  • Standard annoteringstyper.

Jeg forklarer, hvordan man bruger disse komponenter, når vi arbejder os igennem denne artikel.

Erklæring om annoteringstyper med @interface

Du kan erklære en kommentortype ved at angive @ straks efterfulgt af interface reserveret ord og en identifikator. For eksempel erklærer Listing 1 en simpel annoteringstype, som du muligvis bruger til at kommentere trådsikker kode.

Liste 1:ThreadSafe.java

public @interface ThreadSafe {}

Efter at have erklæret denne annoteringstype skal du forud for de metoder, som du anser for trådsikker, med forekomster af denne type ved at forhåndsudgive @ straks efterfulgt af typenavnet til metodens overskrifter. Liste 2 tilbyder et simpelt eksempel, hvor hoved () metoden er kommenteret @ThreadSafe.

Liste 2:AnnDemo.java (version 1)

offentlig klasse AnnDemo {@ThreadSafe offentlig statisk ugyldig hoved (String [] args) {}}

Trådsikker forekomster leverer ingen andre metadata end navnet på annotationstypen. Du kan dog levere metadata ved at tilføje elementer til denne type, hvor en element er en metodeoverskrift placeret i annotationstypens krop.

Ud over at der ikke er kodeorganer er elementer underlagt følgende begrænsninger:

  • Metodeoverskriften kan ikke erklære parametre.
  • Metodeoverskriften kan ikke give en kasteklausul.
  • Metodeoverskriftens returtype skal være en primitiv type (f.eks. int), java.lang.Streng, java.lang.Klasse, en enum, en annotationstype eller en matrix af en af ​​disse typer. Ingen anden type kan angives for returtypen.

Som et andet eksempel præsenterer Listing 3 a At gøre annotationstype med tre elementer, der identificerer et bestemt kodningsjob, specificerer datoen for, hvornår jobbet skal afsluttes, og navngiver koderen, der er ansvarlig for at udføre jobbet.

Liste 3:ToDo.java (version 1)

offentlig @interface ToDo {int id (); String finishDate (); Strengkoder () standard "ikke relevant"; }

Bemærk, at hvert element erklærer ingen parameter (er) eller kaster-klausul, har en lovlig returtype (int eller Snor) og slutter med et semikolon. Endelig afslører det sidste element, at en standardreturværdi kan angives; denne værdi returneres, når en kommentar ikke tildeler en værdi til elementet.

Notering 4 anvendelser At gøre at kommentere en ufærdig klassemetode.

Liste 4:AnnDemo.java (version 2)

public class AnnDemo {public static void main (String [] args) {String [] cities = {"New York", "Melbourne", "Beijing", "Moscow", "Paris", "London"}; sorter (byer); } @ToDo (id = 1000, finishDate = "10/10/2019", coder = "John Doe") statisk ugyldig sortering (Objekt [] objekter) {}}

Liste 4 tildeler et metadataelement til hvert element; for eksempel, 1000 er tildelt id. I modsætning til koder, det id og slutdato elementer skal specificeres; Ellers rapporterer compileren en fejl. Hvornår koder er ikke tildelt en værdi, antager den dens standard "ikke oplyst" værdi.

Java giver en speciel Strengværdi () element, der kan bruges til at returnere en komma-adskilt liste over metadataelementer. Listing 5 demonstrerer dette element i en refactored version af At gøre.

Liste 5:ToDo.java (version 2)

offentlig @interface ToDo {strengværdi (); }

Hvornår værdi() er det eneste element, der er en annoteringstype, skal du ikke angive værdi og = tildelingsoperatør ved tildeling af en streng til dette element. Liste 6 viser begge tilgange.

Liste 6:AnnDemo.java (version 3)

public class AnnDemo {public static void main (String [] args) {String [] cities = {"New York", "Melbourne", "Beijing", "Moscow", "Paris", "London"}; sorter (byer); } @ToDo (værdi = "1000,10 / 10/2019, John Doe") statisk ugyldig sort (Objekt [] objekter) {} @ToDo ("1000,10 / 10/2019, John Doe") statisk boolsk søgning ( Objekt [] objekter, Objektnøgle) {returner falsk; }}

Brug af meta-annotationstyper - problemet med fleksibilitet

Du kan kommentere typer (f.eks. Klasser), metoder, lokale variabler og mere. Denne fleksibilitet kan dog være problematisk. For eksempel vil du måske begrænse At gøre kun til metoder, men intet forhindrer det i at blive brugt til at kommentere andre applikationselementer, som det fremgår af liste 7.

Liste 7:AnnDemo.java (version 4)

@ToDo ("1000,10 / 10/2019, John Doe") offentlig klasse AnnDemo {offentlig statisk ugyldig hoved (String [] args) {@ToDo (value = "1000,10 / 10/2019, John Doe") String [] byer = {"New York", "Melbourne", "Beijing", "Moskva", "Paris", "London"}; sorter (byer); } @ToDo (værdi = "1000,10 / 10/2019, John Doe") statisk ugyldig sort (Objekt [] objekter) {} @ToDo ("1000,10 / 10/2019, John Doe") statisk boolsk søgning ( Objekt [] objekter, Objektnøgle) {returner falsk; }}

I oversigt 7, At gøre bruges også til at kommentere AnnDemo klasse og byer lokal variabel. Tilstedeværelsen af ​​disse fejlagtige kommentarer kan forvirre nogen, der gennemgår din kode eller endda dine egne annoteringsbehandlingsværktøjer. For de tidspunkter, hvor du har brug for at indsnævre en annotationstypes fleksibilitet, tilbyder Java Mål annoteringstype i dens java.lang.annotation pakke.

Mål er en meta-annotation type - en annotationstype, hvis annoteringer annoterer annoteringstyper i modsætning til en ikke-meta-annotationstype, hvis annoteringer kommenterer applikationselementer, såsom klasser og metoder. Det identificerer de typer applikationselementer, som en annoteringstype gælder for. Disse elementer er identificeret ved Mål'S ElementValue [] værdi () element.

java.lang.annotation.ElementType er et enum, hvis konstanter beskriver applikationselementer. For eksempel, BYGGER gælder for konstruktører og PARAMETER gælder for parametre. Notering 8 refaktorer Listing 5'er At gøre annotationstype for kun at begrænse den til metoder.

Liste 8:ToDo.java (version 3)

import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target ({ElementType.METHOD}) offentlig @interface ToDo {strengværdi (); }

I betragtning af refactored At gøre annotationstype, et forsøg på at kompilere Listing 7 resulterer nu i følgende fejlmeddelelse:

AnnDemo.java:1: fejl: annoteringstype gælder ikke for denne form for erklæring @ToDo ("1000,10 / 10/2019, John Doe") ^ AnnDemo.java:6: fejl: annotationstype gælder ikke for denne form for erklæring @ ToDo (værdi = "1000,10 / 10/2019, John Doe") ^ 2 fejl

Yderligere meta-annoteringstyper

Java 5 introducerede yderligere tre meta-annoteringstyper, som findes i java.lang.annotation pakke:

  • Tilbageholdelse angiver, hvor længe kommentarer med den kommenterede type skal bevares. Denne type er tilknyttet java.lang.annotation.RetentionPolicy enum erklærer konstanter KLASSE (kompilator registrerer bemærkninger i klassefilen; virtuel maskine gemmer dem ikke for at gemme hukommelse - standardpolitik), KØRETID (kompilator registrerer bemærkninger i klassefilen; virtuel maskine bevarer dem), og KILDE (compiler kasserer annoteringer).
  • Dokumenteret angiver, at forekomster af Dokumenteret-annoterede kommentarer skal dokumenteres af javadoc og lignende værktøjer.
  • Arvet angiver, at en annoteringstype automatisk nedarves.

Java 8 introducerede java.lang.annotation.Gentagelig meta-annotation type. Gentagelig bruges til at angive, at annotationstypen, hvis erklæring den (meta-) kommenterer, kan gentages. Med andre ord kan du anvende flere annoteringer fra den samme gentagelige annoteringstype til et applikationselement, som vist her:

@ToDo (værdi = "1000,10 / 10/2019, John Doe") @ToDo (værdi = "1001,10 / 10/2019, Kate Doe") statisk ugyldig sort (Objekt [] objekter) {}

Dette eksempel antager det At gøre er blevet kommenteret med Gentagelig annoteringstype.

Behandler annoteringer

Kommentarer er beregnet til at blive behandlet; ellers er der ingen mening i at have dem. Java 5 udvidede Reflection API til at hjælpe dig med at oprette dine egne værktøjer til annoteringsbehandling. For eksempel, Klasse erklærer en Annotation [] getAnnotations () metode, der returnerer en matrix af java.lang.Annotation tilfælde, der beskriver kommentarer, der er til stede på det element, der er beskrevet af Klasse objekt.

Listing 9 præsenterer et simpelt program, der indlæser en klassefil, forhører dets metoder til At gøre annoteringer og output komponenterne i hver fundet kommentar.

Liste 9:AnnProcDemo.java

importere java.lang.reflect.Methode; public class AnnProcDemo {public static void main (String [] args) throw Exception {if (args.length! = 1) {System.err.println ("use: java AnnProcDemo classfile"); Vend tilbage; } Metode [] metoder = Class.forName (args [0]). GetMethods (); for (int i = 0; i <methods.length; i ++) {if (metoder [i] .isAnnotationPresent (ToDo.class)) {ToDo todo = metoder [i] .getAnnotation (ToDo.class); Streng [] komponenter = todo.value (). Split (","); System.out.printf ("ID =% s% n", komponenter [0]); System.out.printf ("Slutdato =% s% n", komponenter [1]); System.out.printf ("Koder =% s% n% n", komponenter [2]); }}}}

Efter at have verificeret, at der er angivet nøjagtigt et kommandolinjeargument (identificering af en klassefil) hoved () indlæser klassefilen via Class.forName ()påberåber sig getMethods () for at returnere en matrix af java.lang.reflect.Methode objekter, der identificerer alle offentlig metoder i klassefilen og behandler disse metoder.

Metodebehandling begynder med at påberåbe sig Metode'S boolean isAnnotationPresent (Class annotationClass) metode til at bestemme, om kommentaren beskrevet af ToDo.-klasse er til stede på metoden. Hvis så, Metode'S T getAnnotation (Class annotationClass) metode kaldes for at opnå kommentaren.

Det At gøre annoteringer, der behandles, er dem, hvis typer erklærer en enkelt Strengværdi () element (se liste 5). Da dette elements strengbaserede metadata er kommasepareret, skal det opdeles i en række komponentværdier. Hver af de tre komponentværdier åbnes og outputes derefter.

Kompilér denne kildekode (javac AnnProcDemo.java). Inden du kan køre applikationen, skal du bruge en passende klassefil med @At gøre bemærkninger om dens offentlig metoder. For eksempel kan du ændre Listing 6'er AnnDemo kildekode, der skal medtages offentlig i dets sortere() og Søg() metodeoverskrifter. Du skal også have en liste over 10'er At gøre annotationstype, som kræver KØRETID fastholdelsespolitik.

Liste 10:ToDo.java (version 4)

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target ({ElementType.METHOD}) @Retention (RetentionPolicy.RUNTIME) offentlig @interface ToDo {strengværdi (); }

Kompilér den modificerede AnnDemo.java og Listing 10, og udfør følgende kommando for at behandle AnnDemo'S At gøre kommentarer:

java AnnProcDemo AnnDemo

Hvis alt går godt, skal du overholde følgende output:

ID = 1000 Slutdato = 10/10/2019 Koder = John Doe ID = 1000 Slutdato = 10/10/2019 Koder = John Doe

Behandling af kommentarer med apt og Java-kompilatoren

Java 5 introducerede en apt værktøj til at behandle annoteringer på en generaliseret måde. Java 6 migreret apt'S funktionalitet i sin javac kompilatorværktøj, og Java 7 udfaset apt, som efterfølgende blev fjernet (startende med Java 8).

Standard annoteringstyper

Sammen med Mål, Tilbageholdelse, Dokumenteretog Arvet, Java 5 introduceret java.lang. udfaset, java.lang.Overrideog java.lang.SuppressWarnings. Disse tre annoteringstyper er designet til kun at blive brugt i en compiler-kontekst, hvorfor deres fastholdelsespolitikker er indstillet til KILDE.

Forældet

$config[zx-auto] not found$config[zx-overlay] not found