Java annotációk
Előre definiált annotációfajták
A 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
@Deprecated
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
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
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
Ezeket csak az annotáció definiálására lehet használni.
@Documented
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
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
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
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
Az 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
Egy 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
Ha 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
A 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
További példák
- További példák (angol)
További információk
- Annotations in Suns Java-Tutorial (angol)
- Annotation Processing Tool (apt) (angol)
- The J2SE 5.0 Annotations Feature bei Sun (angol)
- JSR 175: A Metadata Facility for the JavaTM Programming Language (angol)
- Annotations Java Language Specification (angol)