Verjetno ste že naleteli na situacije, ko se morate združiti metapodatki (podatki, ki opisujejo druge podatke) z razredi, metodami in / ali drugimi elementi aplikacije. Na primer, vaša programska skupina bo morda morala v veliki aplikaciji prepoznati nedokončane razrede. Za vsak nedokončan razred bi metapodatki verjetno vsebovali ime razvijalca, odgovornega za zaključek predavanja, in pričakovani datum zaključka predavanja.
Pred Java 5 so bili komentarji edini prilagodljiv mehanizem, ki ga je Java ponujala za povezovanje metapodatkov z elementi aplikacije. Vendar so komentarji slaba izbira. Ker jih prevajalnik ignorira, komentarji med izvajanjem niso na voljo. Tudi če bi bili na voljo, bi bilo treba besedilo razčleniti, da bi dobili ključne podatke. Brez standardizacije načina določanja podatkovnih postavk se teh podatkov morda ne bo moglo razčleniti.
prenos Prenesite kodo Prenesite izvorno kodo za primere v tej vadnici Java 101. Ustvaril Jeff Friesen za.Nestandardni mehanizmi označevanja
Java ponuja nestandardne mehanizme za povezovanje metapodatkov z elementi aplikacije. Na primer prehodno
rezervirana beseda vam omogoča opomba (povežite podatke s) polji, ki jih je treba med serializacijo izključiti.
Java 5 je z uvedbo vse spremenila opombe, standardni mehanizem za povezovanje metapodatkov z različnimi elementi aplikacije. Ta mehanizem je sestavljen iz štirih komponent:
- An
@interface
mehanizem za prijavljanje vrst pripisov. - Vrste meta-pripisov, s katerimi lahko prepoznate elemente aplikacije, na katere se nanaša vrsta pripisov; za določitev življenjske dobe računalnika pripis (primerek vrste pripisa); in več.
- Podpora za obdelavo pripisov prek razširitve Java Reflection API (o kateri bomo razpravljali v prihodnjem članku), s pomočjo katere lahko odkrijete runtime opombe programa, in splošno orodje za obdelavo pripisov.
- Standardne vrste pripisov.
Pojasnil vam bom, kako uporabljati te komponente, ko se prebijamo skozi ta članek.
Deklariranje vrst pripisov z @interface
Tip pripisa lahko prijavite tako, da določite @
simbolu, ki mu takoj sledi znak vmesnik
rezervirana beseda in identifikator. Na primer, seznam 1 navaja preprost tip pripisov, ki ga lahko uporabite za pripisovanje kod, varnih za nit.
Seznam 1:ThreadSafe.java
javni @interface ThreadSafe {}
Po razglasitvi te vrste pripisov pred primere metode, za katere menite, da so varne za nit, dodajte primere te vrste @
takoj sledi ime tipa v glave metode. Seznam 2 ponuja preprost primer, kjer glavni ()
metoda je označena @ThreadSafe
.
Seznam 2:AnnDemo.java
(različica 1)
javni razred AnnDemo {@ThreadSafe public static void main (String [] args) {}}
ThreadSafe
primerki ne vsebujejo nobenih metapodatkov, razen imena vrste pripisa. Vendar lahko metapodatke dodate tako, da tej vrsti dodate elemente, kjer je element je naslov metode, nameščen v telesu vrste pripisa.
Poleg tega, da nimajo elementov kode, za te elemente veljajo naslednje omejitve:
- V glavi metode ni mogoče prijaviti parametrov.
- Glava metode ne more zagotoviti klavzule o metanju.
- Vrnjeni tip glave metode mora biti primitiven tip (npr.
int
),java.lang.String
,java.lang.Class
, enum, vrsta pripisov ali polje ene od teh vrst. Za vrsto vrnitve ni mogoče določiti nobene druge vrste.
Kot drug primer je v seznamu 3 predstavljen a Narediti
vrsta pripisa s tremi elementi, ki identificirajo določeno kodirno opravilo, določijo datum konca opravila in imenujejo kodir, ki je odgovoren za dokončanje opravila.
Seznam 3:ToDo.java
(različica 1)
javni @interface ToDo {int id (); String finishDate (); String coder () privzeto "n / a"; }
Upoštevajte, da vsak element ne poda nobenega parametra (parametrov) ali vrže klavzulo, ima pravni tip vrnitve (int
ali Vrvica
) in se konča s podpičjem. Prav tako zadnji element razkriva, da je mogoče določiti privzeto vrnjeno vrednost; ta vrednost se vrne, če pripis elementu ne dodeli vrednosti.
Seznam 4 uporablja Narediti
za označevanje nedokončane metode predavanja.
Seznam 4:AnnDemo.java
(različica 2)
javni razred AnnDemo {javna statična praznina main (String [] args) {String [] places = {"New York", "Melbourne", "Peking", "Moscow", "Paris", "London"}; razvrsti (mesta); } @ToDo (id = 1000, finishDate = "10/10/2019", coder = "John Doe") statična razvrstitev praznin (predmet [] predmeti) {}}
Seznam 4 vsakemu elementu dodeli element metapodatkov; na primer, 1000
je dodeljena id
. Za razliko kodirnik
, id
in finishDate
elementi morajo biti navedeni; v nasprotnem primeru bo prevajalnik sporočil napako. Kdaj kodirnik
ni dodeljena vrednost, prevzame privzeto vrednost "n / a"
vrednost.
Java ponuja posebno Vrednost niza ()
element, s katerim lahko vrnete seznam metapodatkov ločenih z vejico. Seznam 5 prikazuje ta element v predelani različici Narediti
.
Seznam 5:ToDo.java
(različica 2)
public @interface ToDo {String value (); }
Kdaj vrednost ()
je edini element vrste pripisa, vam ga ni treba določiti vrednost
in =
operator dodelitve pri dodeljevanju niza temu elementu. Seznam 6 prikazuje oba pristopa.
Seznam 6:AnnDemo.java
(različica 3)
javni razred AnnDemo {javna statična praznina main (String [] args) {String [] places = {"New York", "Melbourne", "Peking", "Moscow", "Paris", "London"}; razvrsti (mesta); } @ToDo (value = "1000,10 / 10/2019, John Doe") static void sort (Object [] predmeti) {} @ToDo ("1000,10 / 10/2019, John Doe") statično logično iskanje ( Object [] predmeti, Object key) {return false; }}
Uporaba vrst metanapisov - problem prilagodljivosti
Lahko označite vrste (npr. Razrede), metode, lokalne spremenljivke in še več. Vendar je ta prožnost lahko problematična. Na primer, morda boste želeli omejiti Narediti
samo na metode, vendar nič ne preprečuje, da bi se uporabljal za označevanje drugih elementov aplikacije, kot je prikazano v seznamu 7.
Seznam 7:AnnDemo.java
(različica 4)
@ToDo ("1000,10 / 10/2019, John Doe") javni razred AnnDemo {public static void main (String [] args) {@ToDo (value = "1000,10 / 10/2019, John Doe") String [] mesta = {"New York", "Melbourne", "Peking", "Moskva", "Pariz", "London"}; razvrsti (mesta); } @ToDo (value = "1000,10 / 10/2019, John Doe") static void sort (Object [] predmeti) {} @ToDo ("1000,10 / 10/2019, John Doe") statično logično iskanje ( Object [] predmeti, Object key) {return false; }}
Na seznamu 7 Narediti
se uporablja tudi za označevanje AnnDemo
razred in mesta
lokalna spremenljivka. Prisotnost teh napačnih pripisov lahko zmede nekoga, ki pregleduje vašo kodo, ali celo vaša orodja za obdelavo pripisov. Za trenutke, ko morate zožiti prilagodljivost vrste pripisov, Java ponuja Cilj
vrsto pripisa v svojem java.lang.annotation
paket.
Cilj
je vrsta metanapisov - vrsta opombe, katere opombe pripisujejo vrste pripisov, v nasprotju z nemetano vrsto pripisov, katere pripisi pripisujejo elemente aplikacije, kot so razredi in metode. Določa vrste elementov aplikacije, za katere je uporabljen tip pripisa. Te elemente označuje Cilj
"s Vrednost ElementValue [] ()
element.
java.lang.annotation.ElementType
je enum, katerega konstante opisujejo elemente aplikacije. Na primer, KONSTRUKTOR
velja za konstruktorje in PARAMETER
velja za parametre. Seznam 8 refaktorjev Seznam 5 Narediti
vrsto pripisov, da jo omejite samo na metode.
Seznam 8:ToDo.java
(različica 3)
uvoz java.lang.annotation.ElementType; uvoz java.lang.annotation.Target; @Target ({ElementType.METHOD}) public @interface ToDo {String value (); }
Glede na predelano Narediti
vrste pripisov, poskus prevajanja seznama 7 zdaj povzroči naslednje sporočilo o napaki:
AnnDemo.java:1: napaka: vrsta pripisa ni uporabna za tovrstno izjavo @ToDo ("1000,10 / 10/2019, John Doe") ^ AnnDemo.java:6: napaka: vrsta pripisa ni uporabna za to vrsto deklaracija @ToDo (vrednost = "1000,10 / 10/2019, John Doe") ^ 2 napaki
Dodatne vrste meta-pripisov
Java 5 je predstavil tri dodatne vrste metanapisov, ki jih najdemo v java.lang.annotation
paket:
Zadrževanje
označuje, kako dolgo naj se obdržijo pripisi z označeno vrsto. Ta vrsta je povezanajava.lang.annotation.RetentionPolicy
enum razglasi konstanteRAZRED
(prevajalnik beleži pripise v datoteko predavanja; navidezni stroj jih ne shrani za prihranek pomnilnika - privzeti pravilnik),RUNTIME
(prevajalnik zapise pripise v datoteko razreda; navidezni stroj jih obdrži) inVIR
(prevajalnik zavrže pripombe).Dokumentirano
označuje, da so primeriDokumentirano
-anotirane pripise mora dokumentiratijavadoc
in podobna orodja.Podedovano
označuje, da se vrsta pripisov samodejno podeduje.
Java 8 je predstavil java.lang.annotation.Ponovljivo
vrsta metanapisov. Ponovljivo
se uporablja za označevanje, da je vrsta opombe, katere izjava (meta-) označuje, ponovljiva. Z drugimi besedami, lahko uporabite več pripisov iz iste ponovljive vrste pripisov za element aplikacije, kot je prikazano tukaj:
@ToDo (value = "1000,10 / 10/2019, John Doe") @ToDo (value = "1001,10 / 10/2019, Kate Doe") static void sort (Object [] predmeti) {}
Ta primer predvideva, da Narediti
je bil označen z Ponovljivo
vrsta pripisa.
Obdelava pripisov
Obvestila so namenjena obdelavi; sicer jih nima smisla imeti. Java 5 je razširil API Reflection, da vam pomaga ustvariti lastna orodja za obdelavo komentarjev. Na primer, Razred
izjavlja Pripis [] getAnnotations ()
metoda, ki vrne matriko java.lang.Anotacija
primeri, ki opisujejo pripise na elementu, ki ga opisuje Razred
predmet.
Seznam 9 predstavlja preprosto aplikacijo, ki naloži datoteko razreda in izpraša njene metode za Narediti
pripisuje komponente vsakega najdenega pripisa.
Seznam 9:AnnProcDemo.java
uvoz java.lang.reflect.Method; javni razred AnnProcDemo {javna statična void main (String [] args) vrže izjemo {if (args.length! = 1) {System.err.println ("uporaba: java AnnProcDemo classfile"); vrnitev; } Metoda [] metode = Class.forName (args [0]). GetMethods (); for (int i = 0; i <methods.length; i ++) {if (metode [i] .isAnnotationPresent (ToDo.class)) {ToDo todo = metode [i] .getAnnotation (ToDo.class); Niz [] komponente = todo.value (). Split (","); System.out.printf ("ID =% s% n", komponente [0]); System.out.printf ("Datum konca =% s% n", komponente [1]); System.out.printf ("Šifrant =% s% n% n", komponente [2]); }}}}
Po preverjanju, da je določen natančno en argument ukazne vrstice (identificiranje datoteke razreda), glavni ()
naloži datoteko razreda prek Class.forName ()
, prikliče getMethods ()
vrniti matriko java.lang.reflect.Method
predmeti, ki identificirajo vse javnosti
metode v datoteki razreda in te metode obdela.
Obdelava metode se začne s klicem Metoda
"s boolean isAnnotationPresent (Class annotationClass)
metoda za ugotavljanje, ali je opomba, ki jo opisuje ToDo.class
je prisoten v metodi. Če je tako, Metoda
"s T getAnnotation (Class annotationClass)
metoda se prikliče za pridobitev pripisa.
The Narediti
pripisi, ki se obdelujejo, so tisti, katerih tipi razglasijo en sam Vrednost niza ()
element (glej seznam 5). Ker so metapodatki tega elementa na osnovi nizov ločeni z vejico, jih je treba razdeliti v niz vrednosti komponent. Nato se dostopi do vsake od treh komponentnih vrednosti in izpiše.
Sestavite to izvorno kodo (javac AnnProcDemo.java
). Preden lahko zaženete aplikacijo, potrebujete ustrezno datoteko predavanja z @Narediti
pripise na svojem javnosti
metode. Lahko na primer spremenite seznam 6 AnnDemo
vključiti izvorno kodo javnosti
v svojem razvrsti ()
in Iskanje()
glave metode. Potrebovali boste tudi seznam 10 Narediti
vrsto pripisa, ki zahteva RUNTIME
politika hrambe.
Seznam 10:ToDo.java
(različica 4)
uvoz java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; uvoz java.lang.annotation.Target; @Target ({ElementType.METHOD}) @Retention (RetentionPolicy.RUNTIME) public @interface ToDo {String value (); }
Sestavite spremenjeno AnnDemo.java
in seznam 10 in za obdelavo izvedite naslednji ukaz AnnDemo
"s Narediti
opombe:
java AnnProcDemo AnnDemo
Če je vse v redu, upoštevajte naslednje rezultate:
ID = 1000 Datum konca = 10.10.2019 Šifrant = John Doe ID = 1000 Datum konca = 10.10.2019 Šifrant = John Doe
Obdelava pripisov s programom apt in prevajalnikom Java
Java 5 je predstavil apt
orodje za splošno obdelavo pripisov. Java 6 se je preselil apt
Je v njegovo funkcionalnost javac
orodje prevajalnika in Java 7 zastarelo apt
, ki je bil nato odstranjen (začenši z Javo 8).
Standardne vrste pripisov
Skupaj z Cilj
, Zadrževanje
, Dokumentirano
, in Podedovano
, Predstavljena Java 5 java.lang.Oskrbljeno
, java.lang.Preveljavi
, in java.lang.SuppressWarnings
. Te tri vrste pripisov so zasnovane za uporabo samo v kontekstu prevajalnika, zato so njihove politike hrambe nastavljene na VIR
.