Opprette en tilpasset kommentar i Java

1. Introduksjon

Java-merknader er en mekanisme for å legge til metadatainformasjon i kildekoden vår. De er en kraftig del av Java, og ble lagt til i JDK5. Kommentarer tilbyr et alternativ til bruk av XML-deskriptorer og markørgrensesnitt.

Selv om vi kan knytte dem til pakker, klasser, grensesnitt, metoder og felt, har ikke merknader i seg selv noen innvirkning på gjennomføringen av et program.

I denne opplæringen skal vi fokusere på hvordan du lager tilpassede merknader, og hvordan vi behandler dem. Vi kan lese mer om merknader i vår artikkel om grunnleggende om merknader.

2. Opprette egendefinerte merknader

Vi skal lage tre egendefinerte merknader med det formål å serieisere et objekt til en JSON-streng.

Vi bruker den første på klassenivå for å indikere kompilatoren at objektet vårt kan serieiseres. Deretter bruker vi den andre på feltene vi vil ha med i JSON-strengen.

Til slutt bruker vi den tredje merknaden på metodenivå for å spesifisere metoden vi skal bruke til å initialisere objektet vårt.

2.1. Kommentareksempel på klassenivå

Det første trinnet mot å lage en tilpasset kommentar er å erklære det ved hjelp av @grensesnitt nøkkelord:

public @interface JsonSerializable {}

Det neste trinnet er å legg til metaanmerkninger for å spesifisere omfanget og målet av vår tilpassede kommentar:

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

Som vi kan se, vår første kommentar har kjøretidssynlighet, og vi kan bruke den på typer (klasser). Dessuten har den ingen metoder, og fungerer dermed som en enkel markør for å merke klasser som kan serieiseres til JSON.

2.2. Merknadseksempel på feltnivå

På samme måte lager vi vår andre kommentar for å markere feltene vi skal inkludere i den genererte JSON:

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

Merknaden erklærer én strengparameter med navnet “nøkkel” og en tom streng som standardverdi.

Når du lager tilpassede merknader med metoder, bør vi være klar over at disse metoder må ikke ha noen parametere, og kan ikke kaste et unntak. Også, returtypene er begrenset til primitiver, streng, klasse, enums, merknader og matriser av disse typene,og standardverdien kan ikke være null.

2.3. Eksempel på merknadsnivåkommentar

La oss forestille oss at før vi serierer et objekt til en JSON-streng, vil vi utføre noen metode for å initialisere et objekt. Av den grunn skal vi lage en kommentar for å markere denne metoden:

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

Vi erklærte en offentlig kommentar med runtime-synlighet som vi kan bruke på klassene våre.

2.4. Bruke merknader

La oss nå se hvordan vi kan bruke våre tilpassede merknader. La oss for eksempel forestille oss at vi har et objekt av typen Person at vi vil serieisere til en JSON-streng. Denne typen har en metode som bruker store bokstaver i for- og etternavn. Vi vil kalle denne metoden før vi serialiserer objektet:

@JsonSerializable offentlig klasse Person {@JsonElement privat streng fornavn; @JsonElement privat streng etternavn; @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 setter}

Ved å bruke våre tilpassede merknader, indikerer vi at vi kan serieisere en Person motsette seg en JSON-streng. I tillegg skal utdataene bare inneholde fornavn, etternavn, og alder felt av objektet. Videre vil vi ha initNames () metoden som skal kalles før serialisering.

Ved å stille inn nøkkel parameteren til @JsonElement kommentar til “personAge”, vi indikerer at vi vil bruke dette navnet som identifikator for feltet i JSON-utgangen.

For demonstrasjonens skyld laget vi initNames () privat, så vi kan ikke initialisere objektet vårt ved å ringe det manuelt, og konstruktørene våre bruker heller ikke det.

3. Behandle merknader

Så langt har vi sett hvordan du lager tilpassede merknader og hvordan du bruker dem til å dekorere Person klasse. Nå, vi skal se hvordan vi kan dra nytte av dem ved å bruke Java's Reflection API.

Det første trinnet vil være å sjekke om objektet vårt er null eller ikke, samt om typen har den @JsonSerializable kommentar eller ikke:

private void checkIfSerializable (Object object) {if (Objects.isNull (object)) {throw new JsonSerializationException ("The object to serialize is null"); } Class clazz = object.getClass (); if (! clazz.isAnnotationPresent (JsonSerializable.class)) {kast ny JsonSerializationException ("Klassen" + clazz.getSimpleName () + "er ikke kommentert med JsonSerializable"); }}

Deretter ser vi etter hvilken som helst metode med @Init-kommentar, og vi utfører den for å initialisere objektets felt:

privat tomrom initializeObject (Objektobjekt) kaster Unntak {Class clazz = object.getClass (); for (Method method: clazz.getDeclaredMethods ()) {if (method.isAnnotationPresent (Init.class)) {method.setAccessible (true); method.invoke (objekt); }}}

Samtalen fra metode.setTilgjengelig(ekte) tillater oss å utføre det private initNames () metode.

Etter initialiseringen gjentas vi over objektets felt, henter nøkkelen og verdien til JSON-elementene, og legger dem i et kart. Deretter oppretter vi JSON-strengen fra kartet:

private String getJsonString (Object object) kaster Unntak {Class clazz = object.getClass (); Kart jsonElementsMap = ny HashMap (); for (Field field: clazz.getDeclaredFields ()) {field.setAccessible (true); if (field.isAnnotationPresent (JsonElement.class)) {jsonElementsMap.put (getKey (field), (String) field.get (object)); }} String jsonString = jsonElementsMap.entrySet () .stream () .map (entry -> "\" "+ entry.getKey () +" \ ": \" "+ entry.getValue () +" \ "") .collect (Collectors.joining (",")); returner "{" + jsonString + "}"; }

Igjen, vi brukte felt.setTilgjengelig(true) fordi det Person objektets felt er private.

Vår JSON-serieklasse kombinerer alle trinnene ovenfor:

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

Til slutt kjører vi en enhetstest for å validere at objektet vårt ble seriellisert som definert av våre tilpassede merknader:

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

4. Konklusjon

I denne artikkelen så vi hvordan du oppretter forskjellige typer tilpassede merknader. Så diskuterte vi hvordan vi kan bruke dem til å dekorere gjenstandene våre. Til slutt så vi på hvordan vi skulle behandle dem ved hjelp av Java's Reflection API.

Som alltid er den komplette koden tilgjengelig på GitHub.