# Java 9: The Good, The Bad, and Private Interface Methods

Source: https://www.yegor256.com/2017/10/03/java9.html

Java 9 [was released](https://blogs.oracle.com/java/java-9-release-now-available)
a few weeks ago. Check the
[release notes](https://docs.oracle.com/javase/9/whatsnew/toc.htm),
they include many interesting features. However, I think that
not everything is as good as Oracle and Java adepts
[seem to picture it](https://www.reddit.com/r/programming/comments/71ls99/java_9_released/).
I see three trends in the Java world, which are good, bad, and ugly,
respectively. Let's start with the good one.


{% jb_picture_body %}

## The Platform

The first trend is an obvious improvement of the platform that compiles Java,
packages JARs, and runs the bytecode. It definitely becomes better with every
new Java release. Here is a list of improvements Java&nbsp;9 made, which are
very useful, without doubt:

  * [JSR 376](http://openjdk.java.net/projects/jigsaw/spec/): Module System a.k.a. [Jigsaw](http://openjdk.java.net/projects/jigsaw/)

  * [JEP 222](http://openjdk.java.net/jeps/222): [`jshell`](http://jakubdziworski.github.io/java/2016/07/31/jshell-getting-started-examples.html)

  * [JEP 238](http://openjdk.java.net/jeps/238): Multi-release JARs

  * [JEP 282](http://openjdk.java.net/jeps/282): [`jlink`](https://blog.idrsolutions.com/2017/05/java-9-jlink-explained-in-5-minutes/)

  * [JEP 158](http://openjdk.java.net/jeps/158): Unified logging

The platform is obviously becoming more mature. This is a _good_ trend.

## The JDK

The second trend, which I've observed since
[Java&nbsp;6](https://www.oracle.com/technetwork/java/javase/features-141434.html),
shows that the JDK, which is essentially a collection of
classes and interfaces designed, developed, and maintained by
[Oracle](https://www.oracle.com/java/index.html),
gets bigger with every new release. In Java&nbsp;9 they added and extended,
besides others, the following:

  * JEP [221](http://openjdk.java.net/jeps/221),
    [224](http://openjdk.java.net/jeps/224)
    [225](http://openjdk.java.net/jeps/225),
    [261](http://openjdk.java.net/jeps/261): Javadoc processing (extended)

  * [JEP 268](http://openjdk.java.net/jeps/268): XML Catalogs (new)

  * [JEP 262](http://openjdk.java.net/jeps/262): TIFF image I/O (new)

  * [JEP 251](http://openjdk.java.net/jeps/251): multi-resolution images (new)

  * [JEP 110](http://openjdk.java.net/jeps/110): HTTP 2.0 client (new)

  * [JEP 236](http://openjdk.java.net/jeps/236): Parser for Nashorn (extended)

Of course some features must be implemented in the JDK itself, like
Unicode support ([JEP 267](http://openjdk.java.net/jeps/267)),
platform-specific Desktop features ([JEP 272](http://openjdk.java.net/jeps/272)),
Spin-Wait Hints ([JEP 285](http://openjdk.java.net/jeps/285)),
compact strings ([JEP 254](http://openjdk.java.net/jeps/254)),
and the process API ([JEP 102](http://openjdk.java.net/jeps/102)).
Their implementation depends on the underlying platform and has
to be provided together with the JVM.

But what is HTTP 2.0 client doing in the JDK, together with
[JAX-RS](https://jcp.org/en/jsr/detail?id=311),
[JPA](https://www.jcp.org/en/jsr/detail?id=338),
[JAX-WS](https://jcp.org/en/jsr/detail?id=224),
[JDBC](https://www.jcp.org/en/jsr/detail?id=221),
and many other things that, in my opinion,
should stay as far away from Oracle as possible?
They are not platform specific and they can be, in a much better way, designed
by the open source community as independent packages.
Aggregating them under one monster umbrella brand is a mistake, I believe.

I think that big corporations are only killing the software market,
instead of making it better, because of the financial and political motives
they expose it to. That's exactly what is happening with JDK. Thanks to
the Oracle monopoly it lacks flexibility and dynamicity in growth. In other
words, we're stuck with what Oracle and its big friends
[think is right](https://news.ycombinator.com/item?id=14301531).

Thus, making JDK bigger is a _bad_ trend. Instead, I believe,
Oracle would only benefit from making it smaller,
delegating everything that is not platform-specific to the open
source community, supporting programmers somehow and promoting open and effective
standardization processes on the market.

## The Language

[Java](https://en.wikipedia.org/wiki/Java_%28programming_language%29)
was developed by
[James Gosling](https://en.wikipedia.org/wiki/James_Gosling) in
[Sun Microsystems](https://en.wikipedia.org/wiki/Sun_Microsystems)
in 1995 as an object-oriented language. There were
[many concerns]({% pst 2016/aug/2016-08-15-what-is-wrong-object-oriented-programming %})
about this claim of object-orientation and I'm also not sure that Java
is more OO than it is procedural. However it is officially object-oriented.

There were many procedural features inherited by Java from C/C++, since
its first version, including
[static methods]({% pst 2014/may/2014-05-05-oop-alternative-to-utility-classes %}),
[NULL]({% pst 2014/may/2014-05-13-why-null-is-bad %}),
[implementation inheritance]({% pst 2016/sep/2016-09-13-inheritance-is-procedural %}),
etc. It was not a perfect object-oriented language and it was not going
to be one, as I understand it. The key idea was to create something that could
be [written once and ran anywhere](https://en.wikipedia.org/wiki/Write_once,_run_anywhere).
However the language was a big deal also, not just the JVM. It was simple and sexy.

Java&nbsp;5 made a serious step forward in 2004 and improved the language by
adding
[generics](https://en.wikipedia.org/wiki/Generics_in_Java),
for-each loop,
[varargs](https://en.wikipedia.org/wiki/Java_syntax#Varargs),
and static import. However, [annotations]({% pst 2016/apr/2016-04-12-java-annotations-are-evil %})
and enumerations were introduced, which helped the language to divert
from the object paradigm to something completely different and procedural.

Java&nbsp;7 added [try-with-resource](http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html)
in 2011, which was a good move, in line with the OOP paradigm.

Java&nbsp;8 added [lambda expressions](http://openjdk.java.net/projects/lambda/) in 2014,
which was a great feature, but absolutely irrelevant to OOP. Lambda and
[Streams API](https://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html)
turned Java into a mix of the object, procedural, and functional
paradigms. [Default methods](https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html)
were also added to interfaces, which turned types into libraries of code. Types into libraries!
It's even worse than
[implementation inheritance]({% pst 2016/sep/2016-09-13-inheritance-is-procedural %}),
if you ask me.

Now Java&nbsp;9 made the next "improvement" to interfaces, allowing them to have
private methods. Private static methods in types! Can you believe it? What will
be the next step? Attributes, in Java&nbsp;10, I guess.

Also, let's take a look at what was done to some core classes in the JDK,
to understand where the language is heading. Just two examples.

**Factory methods for collections**
([JEP 269](http://openjdk.java.net/jeps/269)).
Instead of introducing new constructors and allowing us to do this:

```java
List<Integer> list = new ArrayList<>(1, 2, 3);
```

...in Java&nbsp;9 they created more
[static factory methods]({% pst 2017/nov/2017-11-14-static-factory-methods %})
and made us do this:

```java
List<Integer> list = List.of(1, 2, 3);
```

"Fewer constructors, more static methods!" seems to be the philosophy of those who
introduced this JEP. Needless to say that this is completely against the
very spirit of object-oriented programming. Objects must be created by
constructors, not static methods, no matter what Joshua Bloch
[says](https://amzn.to/2crH5tW). Static methods make the moment of operator
`new` usage invisible for us and that's why the code is way less
maintainable---we simply don't know exactly what class is instantiated and
what the real arguments of its ctor are.

By the way, with [Cactoos](https://www.cactoos.org) you can do it the right way:

```java
List<Integer> list = new ListOf(1, 2, 3);
```

This is OOP.

**New methods in `InputStream`**.
Three new methods were added to the
already [over bloated]({% pst 2016/apr/2016-04-26-why-inputstream-design-is-wrong %}) class
[`InputStream`](https://docs.oracle.com/javase/9/docs/api/java/io/InputStream.html):
`transferTo()`, `readNBytes()`, and `readAllBytes()`.
Now we are supposed to do this, when we want input stream to
copy to an output stream:

```java
input.transferTo(output);
```

It's one of the most typical mistakes young OOP programmers are making: they
make their interfaces big. Just because they need more functionality. I guess the
[interface segregation principle](https://en.wikipedia.org/wiki/Interface_segregation_principle)
is part of the famous [SOLID]({% pst 2017/mar/2017-03-28-solid %})
and is many years old. What's wrong with you, Oracle?
What will the next step be? In Java&nbsp;10 we will also have
`saveToFile()` and `printToConsole()`? How about `emailToAFriend()`?

This is how you would do the same with the
[`IOUtils`](https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/IOUtils.html)
utility class from
[commons-io](https://commons.apache.org/proper/commons-io/):

```java
IOUtils.copy(input, output);
```

It's [not perfect]({% pst 2014/may/2014-05-05-oop-alternative-to-utility-classes %}),
but it's better. The most object-oriented way is to use objects, not
utility classes and static methods. This is how it works in
[Cactoos]({% pst 2017/jun/2017-06-22-object-oriented-input-output-in-cactoos %}):

```java
new LengthOf(new TeeInput(input, output)).length();
```

This is OOP.

<hr/>

In my opinion, Java is getting _uglier_, and this is a trend. Does it mean
that it's time to quit? No! No matter how ugly you are, we will always love you
Java!
