Type Annotations in Java 8: Tools and Opportunities



Type Annotations in Java 8: Tools and Opportunities

Annotations have also played a central role in making developers more productive through techniques such as metaprogramming. The idea is that annotations can tell tools how to generate new code, transform code, or behave at run-time. For example, the Java Persistence API (JPA), also introduced in Java 1.5, allows developers to declaratively specify the correspondence between Java objects and database entities using annotations on declarations such as @Entity. Tools such as Hibernate use these annotations to generate mapping files and SQL queries at run-time.

In the case of JPA and Hibernate, annotations are used to support the DRY (Don't Repeat Yourself) principle. Interestingly, wherever you look for tools for supporting development best-practices, annotations are not hard to find! Some notable examples are reducing coupling with Dependency Injection and separating concerns with Aspect Oriented Programming.

This raises the question: if annotations are already being used to improve quality and boost productivity, why do we need type annotations?

The short answer is that type annotations enable more --- they allow more kinds of defects to be detected automatically and give you more control of your productivity tools.

Type Annotation Syntax

In Java 8, type annotations can be written on any use of a type, such as the following:

@Encrypted String data  List<@NonNull String> strings  MyGraph = (@Immutable Graph) tmpGraph;

Introducing a new type annotation is as simple as defining an annotation with the ElementType.TYPE_PARAMETER target, ElementType.TYPE_USE target, or both targets:

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})  public @interface Encrypted { }

The ElementType.TYPE_PARAMETER target indicates that the annotation can be written on the declaration of a type variable (e.g., class MyClass<T> {...}). The ElementType.TYPE_USE target indicates that the annotation can be written on any use of a type (e.g., types appearing in declarations, generics, and casts).

Once annotations on types are in the source code, like annotations on declarations, they can both be persisted in the class file and made available at run-time via reflection (using the RetentionPolicy.CLASS or RetentionPolicy.RUNTIME policy on the annotation definition). There are two primary differences between type annotations and their predecessors. First, unlike declaration annotations, type annotations on the types of local variable declarations can also be retained in class files. Second, the full generic type is retained and is accessible at run-time.

Although the annotations can be stored in the class file, annotations don't affect the regular execution of the program. For example, a developer might declare two File variables and a Connection variable in the body of a method:

File file = ...;  @Encrypted File encryptedFile = ...;  @Open Connection connection = ...;

When executing the program, passing either of these files to the connection's send(...) method will result in same method implementation being called:

// These lines call the same method  connection.send(file);  connection.send(encryptedFile);

As you'd expect, the lack of runtime effect implies that, while the types of parameters can be annotated, methods cannot be overloaded based on the annotated types:

public class Connection{       void send(@Encrypted File file) { ... }        // Impossible:       // void send( File file) { ... }       . . .  }

The intuition behind this limitation is that the compiler doesn't have any way of knowing the relationship between annotated and un-annotated types, or between types with different annotations.

But wait! -- there's an @Encrypted annotation on the variable encryptedFile corresponding to the parameter file in the method signature; but where is the annotation in the method signature corresponding to the @Open annotation on the connection variable? In the call connection.send(...), the connection variable is referred to as the method's "receiver". (The "receiver" terminology is from the classic Object Oriented analogy of passing messages between objects). Java 8 introduces a new syntax for method declarations so that type annotations can be written on a method's receiver:

void send(@Open Connection this, @Encrypted File file)

Again, since annotations don't affect execution, a method declared with the new receiver parameter syntax has the same behavior as one using the traditional syntax. In fact, currently the only use of the new syntax is so that a type annotation can be written on the type of the receiver.

A full explanation of the type annotation syntax, including syntax for multi-dimensional arrays, can be found on the JSR (Java Specification Request) 308 website.


Read full article from Type Annotations in Java 8: Tools and Opportunities


No comments:

Post a Comment

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts