Java 9 is coming! Just six more months until the scheduled release, so let's have a look at all the shiny new things we get to play with.
But before we do, I have to make a public service announcement: This is the first post since SitePoint's brand new Java channel went public - yeah! (Ok, maybe I'm a little overexcited but as its editor that's kind of my job.) If you like it, you should stick around because there will be more like this.
We'll cover everything related to Java and its ecosystem:
- Java features - from basic (what where the nitty details of
equals
andhashCode
again?), to intermediate (streams anyone?) to advanced (generics, of course) - database stuff (a series about JPA, Hibernate, and alternatives is upcoming),
- web stuff (want to learn about RatPack?)
- other JVM languages (I always wanted to try out Kotlin)
- and much, much more
So if there's any Java in your blood (coffee counts), subscribe to our feed, TODO (what else)
Now, on to Java 9! Because there is so much going on, I created a table of contents:
TODO
(Btw, you can find some of the snippets in this article on GitHub.)
Java Platform Module System
First, let's kick the biggest elephant out of the room: The Java Platform Module System (JPMS) is undoubtedly Java 9's flagship feature and much has been written about it: the grandiose State of the Module System, on this site when I summarized the JVMLS,
on my blog, on other blogs, heck, even Wikipedia has a (useless) article.
With all of these sources we don't have to repeat anything here - so we won't. Instead, let's move on to less known features. And there are so many of them!
Language Changes
When Sun was low on cash, Java 7 only brought some small changes to the language. In an act of sarcastic humor, the project that contained them was dubbed Project Coin. For Java 9 JEP 213: Milling Project Coin refines these and other details.
Private Interface (Default) Methods
Java 8 brought default methods to the table, so that interfaces could be evolved. This went pretty well but there was one unfortunate detail: Reusing code between default methods was unpleasant.
Extracted methods either had to be default methods, which had to be public, or go into some helper class to keep them private:
public interface InJava8 {
default boolean evenSum(int... numbers) {
return sum(numbers) % 2 == 0;
}
default boolean oddSum(int... numbers) {
return sum(numbers) % 2 == 0;
}
// we don't want this to be public;
// but how else do we resuse?
default int sum(int[] numbers) {
return IntStream.of(numbers).sum();
}
}
In Java 9 we can simply have a private interface method:
public interface InJava9 {
// as above
private int sum(int[] numbers) {
return IntStream.of(numbers).sum();
}
}
Neat, hm?
Try-With-Resources on Effectively Final Variables
Have you ever done something like this?
void doSomethingWith(Connection connection) throws Exception {
try(Connection c = connection) {
c.doSomething();
}
}
The variable c
is just there because the try-with-resources statement's syntax required it - the managed resources had to be declared in the statement's head. Java 9 relaxes this. It is now possible to have any resource managed as long as it is effectively final .
So in Java 9 we can use connection
directly:
void doSomethingWith(Connection connection) throws Exception {
try(connection) {
connection.doSomething();
}
}
Diamond Operator for Anonymous Classes
Say we have a simple class Box<T>
and at one point we want to make an anonymous subclass of it. In Java 8 we had to do it like this:
<T> Box<T> createBox(T content) {
// we have to put the `T` here :(
return new Box<T>(content) { };
}
Isn't it obvious that it should be a box of T
? I mean, the compiler can infer the type if we were not creating an anonymous subclass, so why can't it do the same here?
The reason are non-denotable types - types that the compiler understands but the JVM doesn't. In cases like this the compiler might infer a non-denotable type but wouldn't know how to express it for the JVM. So the diamond operator was roundly rejected for anonymous classes.
Java 9 relaxes this and allows the diamond if a denotable type is inferred:
class inJava {
<T> Box<T> createBox(T content) {
// Java 9 can infer `T` because it is a denotable type
return new Box<>(content) { };
}
Box<?> createCrazyBox(Object content) {
List<?> innerList = Arrays.asList(content);
// we can't do the following because the inferred type is non-denotable:
// return new Box<>(innerList) { };
// instead we have to denote the type we want:
return new Box<List<?>>(innerList) { };
}
}
SaveVarargs on Private Methods
Do you know about @SaveVarargs
? You can use it to tell the compiler that your special mixture of varargs and generics is safe. (If you're asking yourself, why it wouldn't be safe, check out this great Q&A on StackOverflow.) A typical use looks like this:
@SafeVarargs
public static <T> Optional<T> first(T... args) {
if (args.length == 0)
return Optional.empty();
else
return Optional.of(args[0]);
}
@SafeVarargs
can only be applied to methods which cannot be overridden (
reason). This obviously includes static, final, and private methods as well as constructors. Or does it? For no apparent reason private, non-final methods could not be annotated before and Java 9 fixes that. One annoyance less.
No More Deprecation Warnings for Imports
If you maintain an old project but are keen on having a warning-free build, you might have come up against the vexing fact that imports of deprecated types cause warnings.
The following class does everything correctly: While it uses a deprecated type, it is deprecated itself so it looks like there is no reason to get a warning.
import java.io.LineNumberInputStream;
@Deprecated
public class DeprecatedImports {
LineNumberInputStream stream;
}
But in Java 8 we do! WTF?! Ok, @SuppressWarnings("deprecation")
to the rescue! Alas, imports can not be annotated and annotating the stream
declaration does not help either. Sad panda.
Again, a little thoughtful tweak is all it takes for Java 9 to shine: Importing a deprecated type no longer causes warnings, so the class above is warning-free.
Now let's move to APIs - new ones and existing ones, high-level and low-level...
Continue reading %The Ultimate Guide to Java 9%
by Nicolai Parlog via SitePoint
No comments:
Post a Comment