Oprettelse af en brugerdefineret kommentar i Java

1. Introduktion

Java-annoteringer er en mekanisme til at tilføje metadataoplysninger til vores kildekode. De er en stærk del af Java og blev tilføjet i JDK5. Annotationer tilbyder et alternativ til brugen af ​​XML-deskriptorer og markørgrænseflader.

Selvom vi kan vedhæfte dem til pakker, klasser, grænseflader, metoder og felter, har kommentarer ikke i sig selv nogen effekt på udførelsen af ​​et program.

I denne vejledning vil vi fokusere på, hvordan man opretter tilpassede kommentarer, og hvordan man behandler dem. Vi kan læse mere om kommentarer i vores artikel om grundlæggende kommentarer.

2. Oprettelse af brugerdefinerede kommentarer

Vi opretter tre brugerdefinerede annoteringer med det formål at serieisere et objekt til en JSON-streng.

Vi bruger den første på klasseniveau til at indikere overfor compileren, at vores objekt kan serieiseres. Dernæst anvender vi den anden på de felter, som vi vil medtage i JSON-strengen.

Endelig bruger vi den tredje kommentar på metodeniveau til at specificere den metode, som vi bruger til at initialisere vores objekt.

2.1. Klassemærkeeksempel

Det første skridt mod at oprette en brugerdefineret kommentar er at erklære det ved hjælp af @interface nøgleord:

public @interface JsonSerializable {}

Det næste trin er at tilføj meta-annoteringer for at specificere omfanget og målet af vores brugerdefinerede kommentar:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.Type) offentlig @interface JsonSerializable {}

Som vi kan se, vores første kommentar har synlighed i runtime, og vi kan anvende den på typer (klasser). Desuden har den ingen metoder og tjener således som en simpel markør til at markere klasser, der kan serieliseres til JSON.

2.2. Eksempel på kommentar på feltniveau

På samme måde opretter vi vores anden kommentar for at markere de felter, som vi skal medtage i den genererede JSON:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.FIELD) public @interface JsonElement {public String key () standard ""; }

Annotationen erklærer én strengparameter med navnet "nøgle" og en tom streng som standardværdi.

Når vi opretter brugerdefinerede kommentarer med metoder, skal vi være opmærksomme på, at disse metoder må ikke have nogen parametre og kan ikke kaste en undtagelse. Også, returneringstyperne er begrænset til primitiver, streng, klasse, enums, annoteringer og arrays af disse typer,og standardværdien kan ikke være nul.

2.3. Eksempel på annotering af metodeniveau

Lad os forestille os, at før vi serieliserer et objekt til en JSON-streng, vil vi udføre en metode til at initialisere et objekt. Af den grund opretter vi en kommentar for at markere denne metode:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface Init {}

Vi erklærede en offentlig kommentar med runtime-synlighed, som vi kan anvende på vores klassers metoder.

2.4. Anvendelse af kommentarer

Lad os nu se, hvordan vi kan bruge vores brugerdefinerede kommentarer. Lad os for eksempel forestille os, at vi har et objekt af typen Person at vi vil serieisere til en JSON-streng. Denne type har en metode, der aktiverer det første bogstav i for- og efternavnet. Vi vil kalde denne metode, før vi serierer objektet:

@JsonSerializable offentlig klasse person {@JsonElement privat streng fornavn; @JsonElement privat streng efternavn; @JsonElement (key = "personAge") privat strengalder; privat strengadresse; @Init private ugyldige initNames () {this.firstName = this.firstName.substring (0, 1) .toUpperCase () + this.firstName.substring (1); this.lastName = this.lastName.substring (0, 1) .toUpperCase () + this.lastName.substring (1); } // Standard getters og setters}

Ved at bruge vores brugerdefinerede annoteringer indikerer vi, at vi kan serieisere en Person modsætter sig en JSON-streng. Derudover skal output kun indeholde fornavn, efternavnog alder felter i det objekt. Desuden ønsker vi initNames () metode, der skal kaldes inden serialisering.

Ved at indstille nøgle parameter for @JsonElement kommentar til “personAge”, vi indikerer, at vi bruger dette navn som identifikator for feltet i JSON-output.

Af hensyn til demonstrationen lavede vi initNames () privat, så vi kan ikke initialisere vores objekt ved at kalde det manuelt, og vores konstruktører bruger heller ikke det.

3. Behandling af bemærkninger

Indtil videre har vi set, hvordan man opretter brugerdefinerede kommentarer, og hvordan man bruger dem til at dekorere Person klasse. Nu, vi skal se, hvordan vi kan udnytte dem ved hjælp af Java's Reflection API.

Det første skridt vil være at kontrollere, om vores objekt er nul eller ej, samt om dens type har @JsonSerializable kommentar eller ej:

private void checkIfSerializable (Object object) {if (Objects.isNull (object)) {throw new JsonSerializationException ("Objektet, der skal serialiseres, er nul"); } Class clazz = object.getClass (); hvis (! clazz.isAnnotationPresent (JsonSerializable.class)) {kast ny JsonSerializationException ("Klassen" + clazz.getSimpleName () + "er ikke kommenteret med JsonSerializable"); }}

Derefter ser vi efter en hvilken som helst metode med @Init-kommentar, og vi udfører den for at initialisere vores objekts felter:

privat tomrum initializeObject (objektobjekt) kaster undtagelse {Class clazz = object.getClass (); for (Metodemetode: clazz.getDeclaredMethods ()) {if (method.isAnnotationPresent (Init.class)) {method.setAccessible (true); method.invoke (objekt); }}}

Opkaldet fra metode.setAccessible(rigtigt) giver os mulighed for at udføre det private initNames () metode.

Efter initialiseringen gentager vi vores objekts felter, henter nøglen og værdien af ​​JSON-elementer og sætter dem på et kort. Derefter opretter vi JSON-strengen fra kortet:

privat streng getJsonString (objektobjekt) kaster undtagelse {Class clazz = object.getClass (); Kort jsonElementsMap = nyt HashMap (); for (Field field: clazz.getDeclaredFields ()) {field.setAccessible (true); hvis (field.isAnnotationPresent (JsonElement.class)) {jsonElementsMap.put (getKey (field), (String) field.get (object)); }} String jsonString = jsonElementsMap.entrySet () .stream () .map (post -> "\" "+ entry.getKey () +" \ ": \" "+ entry.getValue () +" \ "") .collect (Collectors.joining (",")); returner "{" + jsonString + "}"; }

Igen brugte vi Mark.setAccessible(true) fordi Person objektets felter er private.

Vores JSON-serialiseringsklasse kombinerer alle ovenstående trin:

offentlig klasse ObjectToJsonConverter {public String convertToJson (Object object) kaster JsonSerializationException {try {checkIfSerializable (object); initializeObject (objekt); returner getJsonString (objekt); } fange (Undtagelse e) {smid ny JsonSerializationException (e.getMessage ()); }}}

Endelig kører vi en enhedstest for at validere, at vores objekt blev serieliseret som defineret af vores brugerdefinerede kommentarer:

@Test offentlig ugyldighed givenObjectSerializedThenTrueReturned () kaster JsonSerializationException {Person person = ny person ("soufiane", "cheouati", "34"); JsonSerializer serializer = ny JsonSerializer (); String jsonString = serializer.serialize (person); assertEquals ("{\" personAge \ ": \" 34 \ ", \" firstName \ ": \" Soufiane \ ", \" lastName \ ": \" Cheouati \ "}", jsonString); }

4. Konklusion

I denne artikel så vi, hvordan man opretter forskellige typer brugerdefinerede kommentarer. Derefter diskuterede vi, hvordan vi bruger dem til at dekorere vores genstande. Endelig så vi på, hvordan vi behandler dem ved hjælp af Java's Reflection API.

Som altid er den komplette kode tilgængelig på GitHub.