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:
Code Block |
---|
language | java |
---|
title | Photo.java |
---|
linenumbers | true |
---|
|
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.
Code Block |
---|
language | java |
---|
title | PartOfStringRepresentation.java |
---|
linenumbers | true |
---|
|
@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.