This morning Mark Reinhold submitted three brand new JEPs (JDK Enhancement Proposal).
- JEP 300: Augment Use-Site Variance with Declaration-Site Defaults
- JEP 301: Enhanced Enums
- JEP 302: Lambda Leftovers
These proposals are enhancements to the JDK (Java Development Kit) and OpenJDK. A long term roadmap for the JDK projects, a look into what the future of Java might hold.
Let’s dive right in and take a quick look on what these proposals actually are!
JEP 300: Augment Use-Site Variance with Declaration-Site Defaults
When you currently use Java Generics you probably already know about wildcards. It is possible to set lower and upper bounds to generics using the keywords ? extends and ? super. There are two parts to using wildcards, declaration side and use side, this JEP focusses mainly on making the use side easier and more powerful.
Declaration side
It is possible to set a bound with a wildcard on the declaration side:
In this example we’ve declared that the Shelter has to contain Animals. It is possible to create an Shelter<Cat> or Shelter<Dog> now, but not Shelter<Bike>.
Use side
The second way to use wildcards is on the use side. There we can speak of so called in and out-variable wildcards.
The following code uses the ‘extends’ keyword to create the in-variable:
There is also the ‘super’ keyword (not very common) to create an out-variable use side:
So what is JEP 300?
The motivation of the JEP states:
Since invariant uses of these type arguments are less flexible than their wildcard equivalents, while providing no extra power, a reasonable practice is to always use a wildcard when mentioning the type.
It is almost always more powerful and equivalent to use wildcards on the use side. The problem is that this is verbose and adds a lot of noise to your code. The proposal wants to make it possible to declare (at the declaration side) what the default wildcard strategy should be.
For example look at the following code:
The compiler can now automatically treat every use of the type e.g., Function<String, Number> as if it had wildcards Function<? super String, ? extends Number>.
On the use side the proposal says:
Rather than making changes to subtyping, we preprocess the source code so that types like Function<String, Number> are implicitly expanded to Function<? super String, ? extends Number>.
This should make it more powerful and just as readable to using wildcards by default without even noticing them.
JEP 301: Enhanced Enums
The next proposal Mark has submitted is about using Enums with Generics. Look at the following example:
We have an enum with three pets. These pets have an instance of an animal inside them. And we have a way of retrieving them.
But one thing we can’t do it call the method “.bark()” on BELLA, because we don’t know this is a Dog.
The proposal JEP 301 wants to make it possible to correlate a specific type to an enum constant:
Having coupled the Dog type to enum BELLA it should now we possible to call:
JEP 302: Lambda Leftovers
This is turning out to be a rather long blogpost but we’ve reached the final proposed JEP of the day: Lambda Leftovers
Accidental ambiguities
One of the problems people are having with the lambdas at the moment, and this JEP wants to improve, are accidental ambiguities.
For example:
Why are we having this problem? Both methods are possible candidates of the lambda. If we look further and see the return type ‘boolean’ it should be clear we wanted to call the Predicate method and not the Function (which should return a String). Right now this doesn’t work, but it is something the compiler could figure out for us.
Underscores
Up to Java 8 it was perfectly acceptable to use the underscore character ‘_’ as a variable name. But this has been changed, all leading up to JEP 302. In most languages with lambda’s it is possible to denote certain inputs as unused. This is done using the underscore. In Java this causes problems because it is right now a valid variable name.
Starting with Java 8 the use of an underscore as lambda argument caused a warning and from Java 9 the use of an underscore became an error. This allows future Java versions beyond 9 to be able to use the underscore for other purposes. And one of those purposes is to bring it back as a default variable name. Not causing collisions if used multiple times and it can’t be used as variable by calling _.toString() for example.
Shadowing of parameters
Another small change that is proposed is allowing to shadow parameters. For example look at the following code:
In both cases ‘key’ is already defined, can’t be used as a parameter or local variable inside the lambda. The proposal wants to lift this restriction, allowing the use of ‘key’ as a parameter or as a local inside the lambda using so called ‘shadowing’.
One possible drawback is readability, and I too think that this might be a problem. For example:
The second variable “theShadowKey” is taking the place of the first “theInitialKey”. This can be quite confusing because if you delete the second declaration nothing would break. The other variable would come from the shadows and take its place. This feels dangerous and confusing to me, not very ‘Java’-like.
Conclusion
Another day, three new JEPs submitted. Java is moving forward and trying to improve the user experience with genetics and lambdas. These proposals look like good, small, low-impact improvements that can really benefit the common programmer.