Java annotációk
A Java programozási nyelvben annotációnak olyan nyelvi elemet nevezünk, amely lehetővé teszi a metaadatok beépítését forráskódba.[1] Az anotációkat a Java 5.0-s verziójánál vezették be. Az annotációk a programkód elemeihez rendelhetők (csomagokhoz, típusokhoz, metódusokhoz, attribútumokhoz, konstruktorokhoz, lokális változókhoz), plusz információt hordoznak a Java fordító ill. speciális eszközök számára.
Az annotáció @ jellel kezdődik, majd ehhez kapcsolódik a neve. Esetenként vesszővel elválasztva követheti a nevet egy paraméterlista, amelyet kerek zárójelbe foglalunk. Például a következő forráskód-részletben a „deprecated” annotáció megelőzi az A osztályt:
@Deprecated
public class A {}
Az annotáció-processzor egy olyan fordítóprogram-plugin, amely az annotációt a fordításnál kielemzi, és ezzel figyelmeztetéseket és hibajelentéseket nyomhat el, illetve válthat ki, vagy további forráskódokat vagy más adatokat generálhat. Viszont annotációval ellátott kódokat nem tud megváltoztatni. Azok az annotációk, amelyeknél ezt figyelembe vették, futási időben is kielemezhetők a reflexió segítségével.
Az annotációt többek között a Java EE környezetben is használják, hogy osztályokat olyan információkkal bővíthessenek, amelyeket a Java 5-ös verziója előtt külön kellett feltüntetni.
Fontos példák erre például a home és local interfészek, valamint a deployment descriptorok.
A metaadatok speciális Javadoc-kommentekkel is beépíthetőek a forráskódba. Ezek úgynevezett Docletek segítségével értékelhetőek ki. A leggyakrabban használt ilyen eszköz az XDoclet. Ezt a módszert az annotáció bevezetése után továbbra is lehet alkalmazni.
Előre definiált annotációfajták
szerkesztésA Java SE 5.0-ban 7 előre definiált annotációtípus létezik, melyek a java.lang
vagy java.lang.annotation
csomagokban találhatók. Ellentétben a legtöbb annotációval, mindegyik fordítással értékelhető ki. Továbbiakat magunk hozhatunk létre.
A java.lang
csomagban található annotációk
szerkesztés
@Deprecated
szerkesztés
Olyan osztályokat, attribútumokat vagy metódusokat lehet vele jelölni, amelyeket már nem javasolt felhasználni. Ha egy ilyen elem kerül használatba, a fordító figyelmeztetést küld.
Ajánlott egy plusz Javadoc-komment elhelyezése, ami feltünteti, hogy az adott elemet milyen módon lehet helyettesíteni. Példa:
/**
* @deprecated Az A osztály használatát a 10.3-as verziótól az Anew osztály váltja ki.
*/
@Deprecated
public class A {}
@Override
szerkesztés
Ezzel olyan metódust jelzünk, amely a metódus egyik ősosztályának egyik metódusát írja felül. Ebben az esetben a fordítóprogram ellenőrzi, hogy az ősosztály tartalmazza-e a metódust. Amennyiben nem, akkor hibajelzést küld. Pl:
public class A {
public void method() {}
}
public class B extends A {
@Override
public void method() {}
}
@SuppressWarnings
szerkesztés
Ez az annotáció a fordítóprogram bizonyos hibaüzeneteit/figyelmeztetéseit tiltja le. Az annotáció paramétere a letiltandó figyelmeztetések nevét tartalmazó tömb. Pl:
public class A {
@SuppressWarnings({"deprecation"})
public void method() {
DeprecatedClass b = new DeprecatedClass();
}
}
A java.lang.annotation
csomagban található annotációk
szerkesztés
Ezeket csak az annotáció definiálására lehet használni.
@Documented
szerkesztés
Ezt az annotációt meta-annotációként alkalmazzuk: ez biztosítja, hogy az újonnan létrehozott annotációk a javadoc dokumentációba is bekerüljenek.
@Inherited
szerkesztés
Annotációk annotálására alkalmazzák. Ezzel biztosíthatjuk, hogy a saját annotációnkat egy adott osztály örökölje. Az öröklődés kiterjed az alosztályokra is.
@Retention
szerkesztés
Ezt a típust is annotációk annotálására alkalmazzák. Megadja, hogy mikor hivatkozhat önmagára. 3 lehetséges értéke lehet, amelyek a java.lang.annotation.retentionPolicy
enumerációjában jelennek meg:
Class
Runtime
Source
@Target
szerkesztés
Ezt is annotációk annotálására használják. Megmutatja, hogy a program mely elemeire alkalmazható. Az annotáció értékei a java.lang.annotation.ElementType
enumerációban érhető el.
Type
: Csak osztályokra, interfészekre vagy enumerációkra alkalmazhatóMethod
: Csak metódusokra alkalmazhatóAnnotation_Type
: Csak annotációkra alkalmazható
Saját annotáció definiálása
szerkesztésAz annotációk speciális kapcsolódási pontok, ezért a nevüket nagybetűvel írjuk. A specifikáció alapján az interface előtt @ jel áll. Implicit bővítik a java.lang.annotation.Annotation
kapcsolódási pontjait. Más kapcsolódási pontot nem bővíthetnek (vagyis tiltott az extends
), és nem generikusak. A metódusaik paraméter nélküliek és nem generikusak. Visszatérési típusként (return type) csak a következő típusok megengedettek:
- primitív típusok
- felsorolási típusok
- annotáció típusok
- string
- class
- felsorolások (tömbök) ezekből a típusokból
Nem dobhatnak kivételt és nem lehetnek rekurzívak. Sok annotáció nem tartalmaz metódusokat.
@interface Template { }
Más annotációk, ahogy más kapcsolódási pontoknál jellemző, metódusokat tartalmaznak, de csak az előbb felsorolt visszatérési típusúakat. Ha egy annotáció csak egy mezőt tartalmaz, akkor neve a konvencióknak megfelelően "value".
@interface Test {
boolean value();
}
vagy
@interface Author {
String[] value(); // szerző neve
}
vagy
@interface Costumer {
Person[] value();
}
amelynél a személyt felsorolási típusként (enum) vagy annotációként kell definiálni. Pl:
@interface Person {
String name();
int age();
}
Az annotációk konvencióinál gyakran a java.lang.annotation
csomagból választják ki a standard annotációkat. Különösen a @Retention-nel kell feltüntetni, hogy meddig tartsák meg az annotációkat: csak a forrásszövegben (source), a tárolt class-adatoknál (class) vagy a betöltött osztályoknál (runtime). @Target jelzi, hogy melyik programelemeknél használhatóak az annotációk. Például az összes java.lang.annotation
csomagban található annotáció a
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
annotációkkal van ellátva. Ezek a bájtkódba betölthetők, és futási idő alatt kiértékelhetőek, továbbiakban csak annotációtípusokként használhatóak.
Saját annotációk felhasználása
szerkesztésEgy metódus annotáció nélkül mint pl. a @Template, egy osztály elé állítható:
@Template
class SampleClass {
void sampleMethod();
}
Ha az eredménytípus felsorolás, akkor felsorolási literálokat kell alkalmazni:
@Author({"Szerző 1", "Szerző 2"})
String book = "Könyv"
Ha a felsorolás nem tartalmaz elemeket akkor ({}) jellel kell jelezni. De ha csak egy elemet tartalmaz, akkor elhagyhatjuk a belső zárójeleket:
@Author("Szerző")
String anotherBook = "Könyv"
Ha egy annotáció több metódussal rendelkezik, akkor mindegyiknél zárójelben hozzá kell rendelni egy konstans értéket:
@Person(name = "Név", age = 30)
Bill bill = new Bill();
Az annotációknál is van egy módszer, amelyekkel az értéket a névnél meg lehet adni (felesleges, csak olvashatóbb)
@Test(value = true)
Egy komplex annotációt egymásba ágyazva kell alkalmazni.
@Costumer(@Person(name = "Név", age = 30))
class Company { … }
Az annotációknál a metódusoknak kezdőértékeket határozhatunk meg, ekkor felhasználásnál elhagyhatjuk a megfelelő értékek megadását. Mivel az annotációk kapcsolódási pontok, ezért önmaguk annotációval is megjelölhetőek.
@Author("Szerző")
public @interface Test {
boolean buy() default false; // érték nélkül is hívható
}
Annotációk kiértékelése
szerkesztésHa az annotáció az osztály bájtkódjának segítségével betölthető, akkor a reflexió segítségével kiértékelhető. Például megállapítható, hogy egy annotációt megadtak –e vagy sem.
boolean template = SampleClass.class.isAnnotationPresent(Template.class);
Megállapítottuk az annotáció jelenlétét, akkor az értéke is olvasható, pl. hogy a metódus még a tesztelés folyamatában van vagy nem.
boolean isTesting = Template.class.getMethod ( "method", new Class [ ] {}).
Ha az annotáció nem található, akkor a getAnnotation()
által NullPointerException
dobódik. Egy komplex annotációnál az elemeit egyesével kell kiválasztani.
Person costumer = Company.class.getAnnotation(Costumer.class)[0];
Csomagok annotációja
szerkesztésA Java Language Specification engedélyezi a csomagok annotációját, például egy csomag dokumentációjának az előkészítéséhez. Csomagonként maximum egy csomagdeklarációt használhatunk fel egy annotációval. Ha egy csomag annotációt kapna, akkor a Java Language Specification ajánlja egy elkülönített package-info.java adat használatát, amit a csomag jegyzékében ajánlott elhelyezni. Ez az adat tartalmazza a csomagdeklarációt az annotációval együtt.
Jegyzetek
szerkesztés- ↑ Annotations. Sun Microsystems. [2011. szeptember 25-i dátummal az eredetiből archiválva]. (Hozzáférés: 2011. szeptember 30.).
További példák
szerkesztés- További példák (angolul)
További információk
szerkesztés- Annotations in Suns Java-Tutorial (angolul)
- Annotation Processing Tool (apt) (angolul)
- The J2SE 5.0 Annotations Feature bei Sun (angolul)
- JSR 175: A Metadata Facility for the JavaTM Programming Language (angolul)
- Annotations Java Language Specification (angolul)