2013. szeptember 23., hétfő

JavaOne Monday: Enhanced Java SE 8 Metadata

Annotation "fans" were happy at JavaOne to hear about new metadata/annotation features in Java SE 8. This topic was covered in Monday's session "Enhanced Java SE 8 Metadata". Outline below.

Repeating Annotations

Repeating annotations are now allowed. This means that you don't have to (manually) apply the so-called container pattern when declaring more than one instance of an annotation type. E.g. in JPA when you want to use multiple @JoinColumn annotations, what you do now (Java SE 6-7) is wrap them into a single @JoinColumns annotation. In the future this will not be necessary and you can just list the @JoinColumn annotations as needed. You will still need to define the containing annotation, but the compiler transforms the contained ones into it automatically.

So there is one more thing for you to decide when designing annotation types: their cardinality. If you want it to be repeatable, you have to do the followings (samples taken from the official docs):

  • Apply the @Repeatable annotation to it and specify the containing annotation type, i.e.
    public @interface Schedule { ... }
  • Create the containing annotation type. This is required for backward compatibility.
    public @interface Schedules {
        Schedule[] value;

And that's it.

Type Annotations

Another new feature of annotations is the use of type annotations. This means that you can annotate a generic type or other usages of a type. An example to demonstrate this:

List<@NonNull String> list;

Here you annotate the usage of the type String, and this metadata can be used later by tools for whatever purposes. An example of such a tool is the Checker Framework which can perform additional checks on your code based on these kinds of annotations. This happens during compilation as it is a javac plugin.

When designing annotations that can be used this way, you can use two new element types to define where they are allowed: ElementType.TYPE_PARAMETER and ElementType.TYPE_USE.

Parameter Reflection

A new class, named Parameter, appeared in the Reflection API, along with the getParameters() method in the common base class of Constructor and Method, named Executable. So now you can access method parameters with their names and modifiers. The names are not stored in the class file by default; the designers chose an opt-in approach so that parameter names are only stored in the class when asked for. The ideas of explicit, semi-explicit or implicit use of annotations to achieve this were dropped as they did not seem reasonable. (Examples respectively: @IncludeParameterNames on classes/methods, @IncludeParameterNames meta-annotation on other annotations, auto-enabling it for any runtime annotation occurence on a class/method.)

Instead at the moment it can be enabled by the compiler flag -g:vars, just like in previous JDKs. So the new real thing here is the API.

Language Model and Annotation Processing

Access is finally granted to the Language Model API (javax.lang.model) in Java SE 7, and there are some new javax.lang.model features in Java SE 8 (supporting the above features). Also annotation processing is moving to javac, so the apt tool is deprecated in JDK 7 and removed in JDK 8.

Bottom line:

The main constraint for the designers when implementing these features was compatibility of course. The goal is to provides better access and so far missing features to the metadata of the language.

Update: Here is the link for the presentation's site and the slides.

3 megjegyzés: