开发者

How do user annotations work?

开发者 https://www.devze.com 2023-04-12 00:50 出处:网络
I am still fairly new to Java programming and I was looking over a open source project and came across this

I am still fairly new to Java programming and I was looking over a open source project and came across this

public @TileNetworkData int progressPart = 0;   

I have seen the use of @ before but only to do things like @override before a member. To my surprise looking up the definition it brought me to user code

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TileNetworkData {

    int staticSize () default -1; 

}

What is this code doing, and what is it useful for? It looks like it is adding some form of metadata to the field. How is something like this used?

Doing some Googleing I found this is called "Annotations" but everything attached to it w开发者_C百科ent over my head. Any kind of example where something like this would be used would be appreciated.


Annotations are used as "machine-readable metadata" - they describe the fields, methods and classes they label in a way that the compiler and runtime can parse, and possibly even understand. If you are familiar with .NET's attributes, you'll find that Java annotations are used similarly.

For example, the TileNetworkData annotation defined in your example is itself decorated with an annotation Retention(RetentionPolicy.RUNTIME). This tells the compiler to embed the TileNetworkData annotation into the bytecode for the fields it annotates. The same annotation also tells the Java runtime that, when it loads classes with TileNetworkData-annotated fields, it should retain the TileNetworkData annotation for runtime reflection.

Now, your code can reflect over fields of an object to find the TileNetworkData annotations and do something with fields so annotated:

// 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));
    }
  }
}

You can even write code that teaches the Java compiler how to interpret your annotations at compile time, using the apt front end in JDK 5 and javac switches in JDK 6 and later. To make up another lame example, accessing the tile network might take so long that you want to avoid using data from it whenever possible. Hence, you might want to make a list of all classes that include TileNetworkData-annotated fields, so you can review them all and possibly rewrite the ones that don't absolutely need to access the tile network. To do this, you might write an annotation processor that prints out all matching classes, then point apt at the processor when you compile.


Example: Transaction demarcation:

public class TransactionalThing {
    @Transactional
    public void doSomePersistenceStuff() {
        Foo foo = loadAFoo();
        doSomeStuffWith(foo);
        foo.setProcessed(true);
    }
}

There would be other code that looks for methods annotated by @Transactional, starts a transaction before the method is called, and commits (or rolls back) the transaction when it finishes. You can also put information in the annotation about things like, for example, rollback rules:

@Transactional(rollbackFor = SomeException.class,
               noRollbackFor = SomeOtherException.class)

And again, it's just up to the code that scans these transactions to read in those attributes and handle things appropriately.


Annotations are used for meta-data, to describe methods, classes and other types of object.

You can use the to assign meta-data (descriptions of the data) to your java classes. The classic example is @Deprecated, which marks a method as 'not to be used in future'.

For example, you can use them to add configuration information to a java class. If you're using Hibernate (an ORM), you add Annotations to the class saying that this class should be populated from information contained in the database table table_xxx, and the column column_xxx information should be stored in such and such field in the class.

The code that you've posted is defining the Annotation. This will allow this Annotation to be used elsewhere in your code. It's saying that the annotation will be available at runtime, @Retention(RetentionPolicy.RUNTIME), and that Annotation should be available both to the class that uses it and any sub-classes of that class.

For more information, see the answers to How and where are Annotations used in Java?


The meta data can be queried through reflection. Thus, if there was a generic void submitTileNetworkData(Object model) somewhere in the code it could iterate over fields of model and construct a binary dump based on TileNetworkData annotations.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号