Programovanie

Ako opísať kód Java s anotáciami

Pravdepodobne ste sa už stretli so situáciami, kedy je potrebné sa združiť metadáta (údaje, ktoré popisujú ďalšie údaje) s triedami, metódami a / alebo inými prvkami aplikácie. Možno bude napríklad potrebné, aby váš programovací tím identifikoval nedokončené triedy vo veľkej aplikácii. Pre každú nedokončenú triedu by metadáta pravdepodobne obsahovali meno vývojára zodpovedného za dokončenie triedy a predpokladaný dátum dokončenia triedy.

Pred jazykom Java 5 boli komentáre jediným flexibilným mechanizmom, ktorý Java ponúkala na spájanie metadát s prvkami aplikácie. Komentáre sú však zlá voľba. Pretože ich kompilátor ignoruje, komentáre nie sú k dispozícii za behu programu. A aj keby boli k dispozícii, musel by sa text analyzovať, aby sa získali dôležité údajové položky. Bez štandardizácie spôsobu špecifikácie údajových položiek by sa tieto dátové položky mohli analyzovať ako nemožné.

stiahnuť Získajte kód Stiahnite si zdrojový kód pre príklady v tomto výučbe Java 101. Vytvoril Jeff Friesen pre.

Neštandardné anotačné mechanizmy

Java poskytuje neštandardné mechanizmy na asociáciu metadát s prvkami aplikácie. Napríklad prechodný vyhradené slovo vám umožní anotovať (priradiť údaje) polia, ktoré sa majú vylúčiť počas serializácie.

Java 5 zmenila všetko zavedením anotácie, štandardný mechanizmus na združovanie metadát s rôznymi prvkami aplikácie. Tento mechanizmus sa skladá zo štyroch komponentov:

  • An @rozhranie mechanizmus deklarovania typov anotácií.
  • Typy metanotácií, ktoré môžete použiť na identifikáciu prvkov aplikácie, na ktoré sa typ anotácie vzťahuje; na identifikáciu životnosti anotácia (inštancia typu anotácie); a viac.
  • Podpora spracovania anotácií prostredníctvom rozšírenia rozhrania Java Reflection API (o ktorých sa bude diskutovať v budúcom článku), ktoré môžete použiť na objavenie behových anotácií programu, a zovšeobecnený nástroj na spracovanie anotácií.
  • Štandardné typy anotácií.

Pri postupe v tomto článku vám vysvetlím, ako tieto komponenty používať.

Deklarovanie typov anotácií pomocou @ rozhrania

Typ anotácie môžete deklarovať zadaním @ symbol bezprostredne nasledovaný znakom rozhranie vyhradené slovo a identifikátor. Napríklad zoznam 1 deklaruje jednoduchý typ anotácie, ktorý môžete použiť na anotáciu kódu bezpečného pre vlákna.

Výpis 1:ThreadSafe.java

public @interface ThreadSafe {}

Po vyhlásení tohto typu anotácie predponujte metódy, ktoré považujete za bezpečné pre vlákna, s inštanciami tohto typu predponou @ bezprostredne za názvom hlavičky metódy nasleduje názov typu. Zoznam 2 ponúka jednoduchý príklad, kde hlavný() metóda je anotovaná @ThreadSafe.

Výpis 2:AnnDemo.java (verzia 1)

verejná trieda AnnDemo {@ThreadSafe public static void main (reťazec [] args) {}}

ThreadSafe inštancie neposkytujú iné metadáta ako názov typu anotácie. Môžete však dodať metadáta pridaním prvkov k tomuto typu, kde element je hlavička metódy umiestnená v tele typu anotácie.

Okrem toho, že prvky nemajú kódové prvky, podliehajú nasledujúcim obmedzeniam:

  • Hlavička metódy nemôže deklarovať parametre.
  • Hlavička metódy nemôže poskytnúť klauzulu throws.
  • Návratový typ hlavičky metódy musí byť primitívny typ (napr. int), java.lang.String, java.lang.Class, enum, typ anotácie alebo pole jedného z týchto typov. Pre návratový typ nie je možné určiť žiadny iný typ.

Ako ďalší príklad predstavuje zoznam 3 a Robiť typ anotácie s tromi prvkami identifikujúcimi konkrétnu kódovaciu úlohu, špecifikujúci dátum, kedy má byť úloha dokončená, a pomenovaný kódovač zodpovedný za dokončenie úlohy.

Výpis 3:ToDo.java (verzia 1)

public @interface ToDo {int id (); Dokončenie reťazcaDate (); Reťazec coder () predvolené "n / a"; }

Upozorňujeme, že každý prvok nedeklaruje žiadny parameter (parametre) ani vrhá klauzulu, má legálny návratový typ (int alebo String) a končí sa bodkočiarkou. Posledný prvok tiež odhaľuje, že je možné určiť predvolenú návratovú hodnotu; táto hodnota sa vráti, keď anotácia nepriradí hodnotu prvku.

Zoznam 4 použití Robiť anotovať nedokončenú triednu metódu.

Výpis 4:AnnDemo.java (verzia 2)

verejná trieda AnnDemo {public static void main (String [] args) {String [] city = {"New York", "Melbourne", "Peking", "Moskva", "Paríž", "Londýn"}; triediť (mestá); } @ToDo (id = 1000, finishDate = "10.10.2019", coder = "John Doe") statické vyprázdnenie zoradenia (objekty [] objekty) {}}

Výpis 4 priraďuje každému prvku položku metadát; napríklad, 1000 je priradený k id. Na rozdiel od kodér, id a dokončiťDátum prvky musia byť špecifikované; inak kompilátor nahlási chybu. Kedy kodér nemá priradenú hodnotu, predpokladá sa jej predvolená hodnota „n / a“ hodnotu.

Java poskytuje špeciálne Hodnota reťazca() prvok, ktorý možno použiť na vrátenie zoznamu položiek metadát oddelených čiarkami. Zoznam 5 demonštruje tento prvok v upravenej verzii servera Robiť.

Výpis 5:ToDo.java (verzia 2)

public @interface ToDo {String value (); }

Kedy hodnota () je jediný prvok typu anotácie, nemusíte špecifikovať hodnotu a = priraďovací operátor priradením reťazca k tomuto prvku Zoznam 6 ukazuje oba prístupy.

Výpis 6:AnnDemo.java (verzia 3)

verejná trieda AnnDemo {public static void main (String [] args) {String [] city = {"New York", "Melbourne", "Peking", "Moskva", "Paríž", "Londýn"}; triediť (mestá); } @ToDo (hodnota = "1 000,10 / 10/2019, John Doe") statické void triedenie (objekty [] objekty) {} @ToDo ("1000,10 / 10/2019, John Doe") statické boolovské vyhľadávanie ( Object [] objects, Object key) {return false; }}

Používanie typov metanotácií - problém flexibility

Môžete anotovať typy (napr. Triedy), metódy, lokálne premenné a ďalšie. Táto flexibilita však môže byť problematická. Možno budete chcieť napríklad obmedziť Robiť iba na metódy, nič mu však nebráni v tom, aby sa použil na anotáciu ďalších prvkov aplikácie, ako je uvedené v zozname 7.

Výpis 7:AnnDemo.java (verzia 4)

@ToDo („1. 10. 10. 10. 2019, John Doe“) verejná trieda AnnDemo {public static void main (String [] args) {@ToDo (value = „1 000 10.10.2019, John Doe“) String [] mestá = {"New York", "Melbourne", "Peking", "Moskva", "Paríž", "Londýn"}; triediť (mestá); } @ToDo (hodnota = "1 000,10 / 10/2019, John Doe") statické void triedenie (objekty [] objekty) {} @ToDo ("1000,10 / 10/2019, John Doe") statické boolovské vyhľadávanie ( Object [] objects, Object key) {return false; }}

V zozname 7, Robiť sa tiež používa na anotáciu súboru AnnDemo triedy a Mestá lokálna premenná. Prítomnosť týchto chybných anotácií môže niekoho zmiasť pri kontrole vášho kódu alebo dokonca vašich vlastných nástrojov na spracovanie anotácií. Pre časy, keď potrebujete zúžiť flexibilitu typu anotácie, ponúka Java Cieľ typ anotácie v java.lang.annotácia balíček.

Cieľ je a meta-anotačný typ - typ anotácie, ktorej anotácie anotujú typy anotácií, na rozdiel od nemeta-anotačného typu, ktorého anotácie anotujú prvky aplikácie, ako sú triedy a metódy. Identifikuje druhy aplikačných prvkov, na ktoré je typ anotácie použiteľný. Tieto prvky sú označené symbolom Cieľ‘S Hodnota ElementValue [] () element.

java.lang.annotation.ElementType je výčet, ktorého konštanty popisujú aplikačné prvky. Napríklad, KONŠTRUKTOR platí pre konštruktérov a PARAMETR platí pre parametre. Zoznam 8 refaktorov Zoznam 5 Robiť typ anotácie obmedziť iba na metódy.

Výpis 8:ToDo.java (verzia 3)

import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target ({ElementType.METHOD}) public @interface ToDo {String value (); }

Vzhľadom na refaktorované Robiť typu anotácie, výsledkom pokusu o zostavenie záznamu 7 je nasledujúca chybová správa:

AnnDemo.java:1: chyba: typ anotácie sa na tento druh vyhlásenia nevzťahuje @ToDo ("1000,10 / 10/2019, John Doe") ^ AnnDemo.java:6: chyba: typ anotácie sa nevzťahuje na tento druh vyhlásenie @ToDo (hodnota = "10 000, 10/10/2019, John Doe") ^ 2 chyby

Ďalšie typy metanotácií

Java 5 predstavila tri ďalšie typy metanotácií, ktoré sa nachádzajú v dokumente java.lang.annotácia balenie:

  • Zadržanie označuje, ako dlho sa majú anotácie s anotovaným typom uchovať. Tento typ je priradený java.lang.annotation.RetentionPolicy enum deklaruje konštanty TRIEDA (kompilátor zaznamenáva anotácie do súboru triedy; virtuálny stroj ich neuchováva kvôli šetreniu pamäte - predvolená zásada), BEH PROGRAMU (kompilátor zaznamenáva anotácie do súboru triedy; virtuálny stroj ich uchováva) a ZDROJ (kompilátor zahodí anotácie).
  • Zdokumentované označuje, že prípady Zdokumentované-anotované anotácie má dokumentovať javadoc a podobné nástroje.
  • Zdedené označuje, že typ anotácie sa dedí automaticky.

Java 8 predstavila java.lang.annotácia. Opakovateľné meta-anotačný typ. Opakovateľné sa používa na označenie toho, že typ anotácie, ktorej deklaráciu (meta-) anotuje, je opakovateľný. Inými slovami, na prvok aplikácie môžete použiť viac anotácií z rovnakého opakovateľného typu anotácie, ako je to znázornené tu:

@ToDo (hodnota = "1 000,10 / 10/2019, John Doe") @ToDo (hodnota = "1001,10 / 10/2019, Kate Doe") statické void triedenie (objekty [] objekty) {}

Tento príklad to predpokladá Robiť bol anotovaný s Opakovateľné typ anotácie.

Spracovanie anotácií

Poznámky sú určené na spracovanie; inak ich nemá zmysel mať. Program Java 5 rozšíril rozhranie Reflection API, aby vám pomohol vytvoriť vlastné nástroje na spracovanie anotácií. Napríklad, Trieda vyhlasuje Anotácia [] getAnnotations () metóda, ktorá vráti pole java.lang.Anotácia inštancie popisujúce anotácie prítomné na prvku opísanom v Trieda objekt.

Výpis 9 predstavuje jednoduchú aplikáciu, ktorá načíta súbor triedy a zisťuje jeho metódy Robiť anotácií a na výstupe súčasti každej nájdenej anotácie.

Výpis 9:AnnProcDemo.java

import java.lang.reflect.Method; public class AnnProcDemo {public static void main (String [] args) throws Exception {if (args.length! = 1) {System.err.println ("usage: java AnnProcDemo classfile"); návrat; } Metóda [] methods = Class.forName (args [0]). GetMethods (); for (int i = 0; i <methods.length; i ++) {if (methods [i] .isAnnotationPresent (ToDo.class)) {ToDo todo = methods [i] .getAnnotation (ToDo.class); Reťazec [] komponenty = todo.value (). Split (","); System.out.printf ("ID =% s% n", komponenty [0]); System.out.printf ("Dátum dokončenia =% s% n", komponenty [1]); System.out.printf ("Kódovač =% s% n% n", komponenty [2]); }}}}

Po overení, či bol zadaný presne jeden argument príkazového riadku (identifikácia súboru triedy), hlavný() načíta súbor triedy cez Class.forName (), vyvoláva getMethods () vrátiť pole java.lang.reflect.Metóda objekty identifikujúce všetky verejné metódy v súbore triedy a tieto metódy spracuje.

Spracovanie metódy začína vyvolaním Metóda‘S boolean isAnnotationPresent (Class annotationClass) metóda na určenie, či je anotácia opísaná v ToDo.class je prítomný na metóde. Ak je to tak, Metóda‘S T getAnnotation (Class annotationClass) na získanie anotácie sa volá metóda.

The Robiť spracovávané anotácie sú tie, ktorých typy deklarujú jednu Hodnota reťazca() prvok (pozri Výpis 5). Pretože metadáta tohto reťazca založené na reťazcoch sú oddelené čiarkami, je potrebné ich rozdeliť do radu hodnôt komponentov. Ku každej z troch zložiek sa potom pristupuje a vydáva sa.

Zostavte tento zdrojový kód (javac AnnProcDemo.java). Pred spustením aplikácie budete potrebovať vhodný súbor triedy s @Robiť anotácie k jeho verejné metódy. Môžete napríklad upraviť zoznam 6 AnnDemo zahrnúť zdrojový kód verejné v jeho sort () a Vyhľadávanie() hlavičky metódy. Budete tiež potrebovať zoznam 10 Robiť typ anotácie, ktorý vyžaduje BEH PROGRAMU retenčná politika.

Výpis 10:ToDo.java (verzia 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) public @interface ToDo {String value (); }

Zostavte upravené AnnDemo.java a Výpis 10 a vykonajte nasledujúci príkaz na spracovanie AnnDemo‘S Robiť anotácie:

java AnnProcDemo AnnDemo

Ak všetko pôjde dobre, mali by ste sledovať nasledujúci výstup:

ID = 1000 Dátum dokončenia = 10.10.2019 Coder = John Doe ID = 1000 Dátum dokončenia = 10/10/2019 Coder = John Doe

Spracovanie anotácií pomocou apt a kompilátora Java

Java 5 predstavila trefný nástroj na všeobecné spracovanie anotácií. Java 6 migrovala trefnýFunkčnosť do svojej javac nástroj na prekladanie a podpora Java 7 je zastaraná trefný, ktorý bol následne odstránený (počnúc Java 8).

Štandardné typy anotácií

Spolu s Cieľ, Zadržanie, Zdokumentovanéa ZdedenéBola predstavená Java 5 java.lang. zastarané, java.lang.Overridea java.lang.SuppressWarnings. Tieto tri typy anotácií sú určené na použitie iba v kontexte kompilátora, a preto sú ich zásady uchovávania nastavené na ZDROJ.

Zastarané

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