Project Amber: The Future of Java Exposed
If all goes according to plan (Project Jigsaw we’re looking at you), Java 9 is set to launch in less than 100 days. You can join the countdown to its release right here. It will come packed with a long list of new and upgraded features, some we can’t wait to see in action.
However, there are a few features that weren’t ready for Java 9, and that’s where Project Amber comes in, so these features could become a reality. What does it mean? Let’s find out.
Focusing on Var/Val, Enums and Lambda
Project Amber was first introduced last January when Brian Goetz, Java Language Architect, proposed creating a project for exploring and incubating smaller, productivity-oriented Java language features.
The main prerequisite for features that’ll be a part of this project: they have been accepted as candidate JEPs, also known as JDK Enhancement Proposal. It’s the process in which Oracle collects proposals for enhancements to the Java Development Kit and OpenJDK. Approved proposals continue down the road to become actual features in Java.
Goetz points out that this project is not the place to think of or discuss new and random ideas to improve Java, and that “the whole rest of the internet is still available for that”.
On March 16th Goetz welcomed project Amber into the Java community, along with the first three Java Enhancement Proposals adopted by it:
– Local Variable Type Inference (JEP 286) – Extend type inference to declarations of local variables with initializers
– Enhanced Enums (JEP 301) – Features and abilities that will make enums better
– Lambda Leftovers (JEP 302) – Improve the usability of lambda
Why did these three projects got such special attention? Let’s find out.
Meet the New Features of Project Amber
Local Variable Type Inference
One of the main issues most developers have with Java is that it’s too verbose. While this might be a good thing when reading and trying to understand what other developers had in mind when a function was written, it might get tedious when actually writing those functions.
This feature suggests adding some syntactic sugar to Java in order to simplify it. It would allow declaring variables without having to specify the associated type. For example, this:
List<String> list = new ArrayList<String>(); final Stream<String> stream = getStream();
Will be replaced with this:
var list = new ArrayList<String>(); val stream = getStream();
If you want to learn more about this feature, and how the community feels about it check out our hands-on overview of the New Java Local Variable Type Inference Language Feature.
Enhanced Enums
The goal of this feature is to enhance the expressiveness of the enum construct in the Java language. As stated out in the proposal, Java enums are a powerful and commonly used construct. They allow grouping of constants, where each one is a singleton object. It enables a variable to be a set of predefined constants, when the variable must be equal to one of the values that have been predefined for it. Days of the week, for example.
The enhancement will allow type-variable in enums (generics support), that can extend the enum. It will also offer performing sharper type-checking for enum constants, to verify and enforce the constraints of the enum.
An enum with generics support will allow us to indicate sets of keys with their associated type, and we’ll have the ability to add methods to individual items. These two features will work together to enable enum constants to carry constant-specific type information as well as constant-specific state and behavior. Enhanced enums will allow us to define enums with generic types. An example that can show some value for this feature is when representing mathematical constants:
public enum MathematicalConstants < T > { E < Double > (Math.PI), PI < Double > (Math.E), ZERO < Integer > (0), ONE < Integer > (1), i < Complex > (new Complex(0, 1)) private MathematicalConstants(T underlyingObject) { this.underlyingObject = underlyingObject; } }
In this example, we can add support for additional methods while still enjoying type safety for each method. The ability to pass in the different types to the enum’s constructor when underlyingObject doesn’t have to be type Object, showcases the elegance this feature can bring to the table.
Another useful application of enhanced enums is reducing boilerplate code that converts between different data types. For instance, jdbc types to Java types. It can help increase the ability of our code to self document, and avoid code smells like “instanceOf” checks.
Lambda Leftovers
Project Lambda was released with Java 8 in 2014, but there’s always room for improvements. The idea here is to improve the usability of lambda expressions and method references by enhancing the disambiguation of functional expressions in method contexts.
This feature also focuses on completing the rehabilitation of the underscore character to indicate unused lambda parameters, and allowing lambda parameters to shadow variables in enclosing scopes.
The concept of using an underscore as a symbol of an unnamed lambda parameter already exists in other languages, and the goal is to make it a part of Java as well. The use is pretty straightforward, and will look like this:
BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);
Why is it important? Since it will allow stronger static checking of unused arguments, and also allows multiple arguments to be marked as unused. However, it might be difficult to execute this option, since the underscore is already a valid identifier and it will require some adjusting and compatibility for it to work.
The Side Projects of Java
Project Amber joins a long group of Java “side projects”, such as Valhalla, for working with immutable and reference-free objects, Shenandoah that aims to reduce GC pause times and XRender Graphics Pipeline, with a goal to create a new Java2D graphics pipeline.
Two of the more spoke-of projects are Lambda and Jigsaw. Project Lambda was introduced on March 2014, as part of Java 8, and it brought lambda expressions and streams into Java. Project Jigsaw is about to be part of Java 9, aiming to make Java modular and break the JRE to interoperable components.
Both projects took a lot of hard work – Lambda was first introduced on December 2009, and it took a little over 5 years to become an actual part of Java. Jigsaw was introduced on December 2008, followed by almost 9 and a half years of work.
It doesn’t necessarily mean that project Amber will have the same timeline, but it’s a good indication as to how long it takes to incorporate major features into Java. However, there’s a little ray of hope within the announcement of this project.
Along with the mailing lists projects usually get, Goetz published the official repo. Unlike similar projects, since there are multiple JEPs the team will be working on, the work will be done in branches, when the default one will be synced to jdk10. Does that mean that Amber might be a part of the next Java version? We’ll have to wait and see.
Why Amber?
If you’re wondering about the name and how it was chosen, Nicolai Parlog, Java developer and the editor of SitePoint’s Java section tweeted this question to Brian Goetz himself. He got the simple answer of “why not?”.
However, Goetz suggested to hold a contest to come up with candidates. He hand-picked the winner, that offered the following explanation: “
Or more probable: amber was called elektron in Greek, which might mean "beaming Sun" (according to Wikipedia)
— MaartenVanPuymbroeck (@kwakeroni) March 28, 2017
And you have to admit that it sounds cool.
Final Thoughts
Java is a massive language with a lot of features, abilities and programmers. Project Amber joins the list of features that are already-in-progress, all with the same goal – to help the developing phase move faster, and answer the needs and desires of Java engineers and developers.
Now there are two main questions – which other proposals Project Amber will adopt, and how long will it take them to become a Java reality.
Reference: | Project Amber: The Future of Java Exposed from our JCG partner Henn Idan at the OverOps blog. |
I think you have an error in the code:
E (Math.E),
PI (Math.PI),
This should work better, if you want to use these constants later on ;)