Az eddigi legjobb dolog - ami a Java nyelvvel történt - az annotációk bevezetése volt. Egy csomó keretrendszer alapul annotációkon, mint a JPA, a Seam vagy a Spring 2.5, de a fejlesztők jó része még nem készített saját annotációt. A The Wrong Code blog írója első blogbejegyzésében rögtön egy kisregényt írt az annotációkról, mégpedig a saját készítésű annotációkról. A programozók népe ugyanis alapvetően lusta (ezért lettek programozók), így amíg nem muszáj, nem használnak újabb technológiákat, mert azt meg kell tanulni. Nézzük a blogban említett példát, amely egy fotó reprezentációja:
public class Photo { private long id; private String contentType; private String caption; private byte[] data; @Override public String toString() { return String.format("Photo(id=%d,caption=%s,contentType=%s)",id, caption, contentType); } }
Az @Override annotációval talán mindenki találkozott, a lényege, hogy egy ilyenformán jelölt metódusnak felül kell definiálnia egy azonos nevű és tulajdonságú metódust az ősosztályban. Ez elsőre feleslegesnek tűnhet, azonban nagyobb rendszerek esetén sokszor előfordul, hogy változik az API és az implementációt megvalósító osztályokban pedig benne maradnak olyan források, amelyek eredetileg felüldefiniáltak egy ősosztálybeli metódust, amit viszont eltüntettek a tervezők. Tűzzük ki feladatnak, hogy egy annotációval jelezzük a toString metódusunknak: az adott attribútumot írja ki, ha az osztály példányát valamilyen (naplózási, hibakeresési, stb.) okból kiíratnánk.
@Retention(RetentionPolicy.RUNTIME) public @interface PartOfStringRepresentation { } public class Photo { @PartOfStringRepresentation private long id; @PartOfStringRepresentation private String caption; @PartOfStringRepresentation private String contentType; private byte[] data; @Override public String toString() { try { StringBuilder builder = new StringBuilder(); builder.append(getClass().getSimpleName()); builder.append('('); Field[] declaredFields = getClass().getDeclaredFields(); boolean firstField = true; for (int i = 0; i < declaredFields.length; ++i) { Field declaredField = declaredFields[i]; if (declaredField.getAnnotation(PartOfToStringRepresentation.class) != null) { if (firstField) { firstField = false; } else { builder.append(", "); } builder.append(fieldName); builder.append('='); builder.append(fieldValue); } } builder.append(')'); return builder.toString(); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } }
Első ránézésre erőteljesen összetett lett a toString metódusunk, viszont észre kell venni, hogy mindez a nagy kódbázis kiszervezhető egy külön osztályba, s ezek után már csak az annotáció dönti el, hogy egy attribútum része lesz-e a kiírásnak vagy sem. Több tucat entitás esetén már biztos megéri használni, használjuk.
4 Comments
Auth Gábor AUTHOR
tvik
Unknown User (kuvera)
Én több saját annotációt írtam már, nagyon hasznos dolog. Példa: tetszőleges entitásból JSP űrlap automatikus legyártása. Az űrlapon adatmezőnként kell a megnevezés címke és az űrlapmező típusa (text, select, checkbox)
A JSP generátor kap egy entitást, és az annotációkből kigyűjt olyan adatot, aminek közvetett köze van csak az entitás működéséhez. A type="/" checkboxot gyárt, a "-" kezdetű pedig select listát, aminek tartalmára a string utal.
Auth Gábor AUTHOR