The overview of JSR 308 (Annotations on Java Types) took an important stage as part of last week's JavaOne presentation about new language features proposed for Java SE7 ("TS-5581: Upcoming Java Programming-Language Changes"). Other new features covered by the presenters - Alex Buckley (Sun Microsystems), Michael Ernst (MIT) and Neal Gafter (Google) - were: Improved catch clauses (multi-catch), Safe re-throw, and Java Modules.
JSR 308 attempts to solve two issues currently present in the Java 1.5 annotations:
- Syntactic limitation on annotations: Annotations can only be written on declarations
- Semantic limitation of the type system: The type system does not prevent enough bugs
The solutions provided by JSR 308 to these problems are:
Extend the language syntax to permit annotations in more locations which include: method receivers, generic type arguments, arrays, typecasts, type tests, object creation, type parameter bounds, class inheritance and throws clauses.
Enable creation of more powerful annotation processors through the introduction of pluggable type systems. Code annotated with type qualifiers can be analyzed by type checkers which will warn about violations (bugs).
Following this presentation, Michael Nygard wrote about JSR 308 in the When Should You Jump? JSR 308. That's When. post about his views on the impact of the JSR 308 on the language and the Java developers. After providing a few examples in his post on how these annotations can be used, Nygard argues that this JSR alongside with the generics introduced in Java 1.5 increase the language complexity with little added benefit:
Every language has a complexity budget. Java blew through it with generics in Java 5. Now, seriously, take another look at this:
@NotEmpty List<@NonNull String> strings = new ArrayList<@NonNull String>()>
Does that even look like Java? That complexity budget is just a dim smudge in our rear-view mirror here. We're so busy keeping the compiler happy here, we'll completely forget what our actual project it.
Nygard sees the timing of the new proposal even more worrisome given the increasing interest among developers towards dynamic languages:
All this is coming at exactly the worst possible time for Java the Language. The community is really, really excited about dynamic languages now. Instead of those contortions, we could just say:
var strings = ["one", "two"];
Now seriously, which one would you rather write? True, the dynamic version doesn't let me enlist the compiler's aid for enforcement. True, I do need many more unit tests with the dynamic code. Still, I'd prefer that "low ceremony" approach to the mouthful of formalism above.
Nygard believes that Java developers should jump to a new language when JSR 308 becomes part of the language and concludes:
So, getting back to that mainstream Java developer... it looks like there are only two choices: more dynamic or more static. More formal and strict, or more loosey-goosey and terse. JSR 308 will absolutely accelerate this polarization.
Unsurprisingly, this point of view generated a number of reactions from various commentators. cfagan responded to another commentator who found that annotations are a convenient escape route for developers to not have to read the API docs or focus and think about what they are doing:
In the end the code is the ultimate documentation. These annotation attempt to express intent. Which is something that can be lost with documentation when it's not kept up to date, or missing. I agree that superior talent produces superior results, regardless of language. Still moving any runtime error to compile time speeds up the development process and saves the overhead of a bug that would otherwise be caught by testing.
Josef wrote about the optional nature of the annotations and shared his view about their probable adoption path. He argues that Nygard:
[...] talks like the annotations JSR 308 enables are mandatory and that all Java programmers have to write them from the moment JSR 308 is accepted. I expect that very few Java developers will be using them in the beginning. It will only be companies that write very high assurance software and that need these kinds of things to specify correctness condition and check them automatically or semi-automatically.
and explains how they are different from generics:
The nice thing with these annotations is that they are always safe to ignore. You cannot of course do that with generics because then you wouldn't know what type your program had. But with JSR 308 annotations you can code along just fine without paying the least bit of attention to them. They only come in play when you start using a checker that actually cares about the annotations.
The "Upcoming Java Programming-Language Changes" presenters summarized the main principles by which new features to be added to the Java language should be evaluated, as follows:
- Encourage high-level practices (Do the right thing)
- Covet clarity (Do the thing right)
- Prefer static typing (Stay safe)
- Isolate the language from APIs (Stay abstract)
Based on the context of these principles, JSR 308 seems to fit well with the general future direction of the Java language. Are the recent discussions around the addition of this new feature representative of certain diverging interpretations of these principles or do they signal concerns with the principles guiding the Java language evolution set forward by its stewards?