Ugrás a tartalomhoz

Java annotációk

A Wikipédiából, a szabad enciklopédiából
A lap korábbi változatát látod, amilyen 2804:d55:52f3:da00:6870:b0f9:2788:6815 (vitalap) 2021. március 28., 01:09-kor történt szerkesztése után volt. Ez a változat jelentősen eltérhet az aktuális változattól.
ameli evezetése után továbbra is lehet alkalmazni

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 információk