Аннотации используются в качестве «машиночитаемых метаданных» - они описывают поля, методы и классы, которые они помечают, таким образом, что компилятор и среда выполнения могут анализировать и, возможно, даже понимать. Если вы знакомы с .NET-атрибутами , вы обнаружите, что аннотации Java используются аналогично.
Например, аннотация TileNetworkData
, определенная в вашем примере, сама украшена аннотацией Retention(RetentionPolicy.RUNTIME)
. Это говорит компилятору о встраивании аннотации TileNetworkData в байт-код для полей, которые он аннотирует. Эта же аннотация также сообщает среде выполнения Java, что при загрузке классов с полями, аннотированными TileNetworkData, она должна сохранять аннотацию TileNetworkData для отражения во время выполнения.
Теперь ваш код может отражать поля объекта, чтобы найти аннотации TileNetworkData и что-то делать с аннотированными полями:
// I haven't even compiled this code, and even if it works, it's still insane.
// (others who know annotations better should feel free to edit or replace)
public void copyTileNetworkDataToCache (Object data, Cache<?> cache) {
for (Field f : data.getClass().getFields()) {
if (f.isAnnotationPresent(TileNetworkData.class)) {
cache.save(f.get(data));
}
}
}
Вы даже можете написать код, который учит Java-компилятор , как интерпретировать ваши аннотации во время компиляции , используя apt
внешний интерфейс в JDK 5 и javac
в JDK 6 и более поздних версиях. Чтобы создать еще один неудачный пример, доступ к сети плиток может занять так много времени, что вы захотите по возможности избегать использования данных из нее. Следовательно, вы можете захотеть составить список всех классов, включающих поля, аннотированные TileNetworkData, чтобы вы могли просмотреть их все и, возможно, переписать те, которые абсолютно не нужны для доступа к сети листов. Для этого вы можете написать процессор аннотаций, который распечатывает все подходящие классы, а затем указать apt
на процессор при компиляции.