Core Java

Guide to Features Changes from Java 8 to Java 15

In this article, we provide a guide to features changes from Java 8 to Java 15.

Do you ever feel like you’re falling behind everyone else? Well, I’m here to confirm those suspicions, and I’ll throw in a cheeky Bob Dylan quote that I’ve been itching to pull out.

You better start swimming, or you’ll sink like a stone

-Bob Dylan

1. Java 8 to Java 15

Many developers seemed to rest on their laurels after the general release of the game-changer that was JDK 8. Meanwhile, the landscape of the JVM continued to change. As well as the growth in popularity and feature set of two JVM languages, namely Kotlin and Scala, there has been a steady — and getting steadier — release of versions of the JDK. If you stopped updating the version of your compiler, prior to 8, you may need a life raft, and I can recommend a packed lunch. Otherwise, for the purpose of this article, I’ll assume you are more than familiar with the changes introduced by JDK 8.

JDK 15 has only been on general release since August 22nd, so I’ll leave that for last. Chronologically, then, here is a snap-shot of JDK’s evolution:

2. JDK 9

This was not as popular as its predecessor and although had a tough act to follow, it was itself, a long time coming and contained many useful additions.

You can also check our Java 9 New Features Tutorial.

2.1 REPL

Read Eval(uate) Print Loop. Java finally got its own REPL, like most modern languages; a student could quickly practice, while a professional developer could test new language features, without the need for a heavy IDE.

2.2 Immutable Collections, Quickly

List immutableList = List.of(); Java 9 saw the introduction of helper methods which could create an immutable collection — list, for example — of a group of arguments, this is really useful as a quick way of creating any collection, while also encouraging best practice, similar to Kotlin’s default of immutability. e.g.:

A new way to quickly instantiate an immutable map.

Static Composition of a Map

e.g. Map.of(1, "one", 2, "two", 3, "three")

2.3 Private Interface methods

This is an enhancement that I can see has many applications in the area of neatness, but it does exactly what it says on the tin.

private methods on Interfaces

public interface AbstractThingy {
   private Long calculateSomething() {
      //method implementation
      return 22L;
      }
   }
}

Obviously these private methods will only be usable by default methods.

2.4 Module System

This is the most important new feature from Java 9. It represents a paradigm shift for the language. Of course, there is no necessity to change your mode of thinking but the infrastructure is there, should you get the urge. It is this system that is being referred to as “Project Jigsaw”

2.5 Improved Javadocs

Javadocs will be familiar to learners of the language, but they’re also useful for seasoned developers as a reference. Java 9 introduced some welcome enhancements, in the form of, for example, googlesque searching functionality. This along with Stackoverflow would have made my undergrad much easier.

2.6 New Http Client

Java 9 saw a much-needed enhancement to how Java deals with HTTP, following the advent of http2 and WebSockets..

2.7 Improve Stream API

There are some improvements, including three new methods, on the Stream interface (introduced with Java 8). The three new methods are the self-explanatory trio, of dropWhile, takeWhile, and of nullable. Iterate received an overload, which allows a developer to provide a predicate for when iterating should stop.

To allow for the provision of a stopping rule:

New Iterate Functionality

        iterate(0, i -> i < 10, i -> x + 1).forEach(num -> System.out.println(immutableMap.get(num)));

import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class Demo9 {
    interface InterfaceWithPrivateMethod{
        private long calculateSomething(){
            return 11L;
        }
        default int addOddNumbersToSomething(int... nums) {
            int start = 0;
            for (int num:nums) {
                start+=num;
            }

            return start;
        }

    }

    public static void main(String[] args) {
        Stream.iterate(0, i -> i < 5, i -> i + 1)
                .forEach(System.out::println);
        List immutableList = List.of(2, 3);
        Map<Integer, String> immutableMap = Map.of(1, "one", 2, "two",
                3, "three", 4, "four", 5, "five",
                6, "six", 7, "seven", 8, "eight",
                9, "nine", 10, "ten");
        System.out.println(immutableMap.get(1));

    }

}

Output

0
1
2
3
4
one

Process finished with exit code 0


That does it for my summary of the changes in JDK 9. As with all the versions listed below (AWAVLB), you are encouraged to delve deeper because, AWAVLB, it’s not exhaustive.

3. JDK 10

3.1 Local Type Inference

This is the most noteworthy among the offerings of 10, who was very unlucky to be following 8 and 9, but that’s how it goes.

As with Javascript (and Kotlin, with ‘Val’), the var keyword is indicative that the compiler/interpreter must figure out what the data type is, but the var keyword is limited in scope to local variables.

New ‘var’ keyword

var jackpot = 7;

System.out.println("77"+jackpot);
public class Demo10 {
    public static void main(String args[]){
        var jackpot = 7;
        System.out.println("77"+jackpot);

    }
}

Output

777

Process finished with exit code 0

Most other enhancements dealt with the nuts and bolts of efficiency and garbage collection.

4. JDK 11

Not much to report here in terms of changes to the language, but Java continued its drive for efficiency. There is one thing that is worth a mention.

You can also check our Java 11 New Features Tutorial.

The inclusion of the oft-developer-implemented ‘isBlank’, as a nice-to-have member method on String.

New Member method on String

if("".isBlank())
	System.out.println("Blank!");
public class Demo11 {
    public static void main(String[] args) {
        String blank = "";
        if(blank.isBlank())
            System.out.println("blank!");
    }
}

Output

blank!

Process finished with exit code 0

5. JDK 12

An interesting change in 12 — I hope you don’t mind my skipping the formality of saying ‘JDK, version’ — is the inclusion of an option to use the switch statement as an expression. I’ll say this for Kotlin, if it has done anything, it has shown Java that it must stay innovative.

You can also check our Java 12 New Features Tutorial.

Below, I have leveraged the var keyword, introduced in 10, to demonstrate the power of using Switch as an expression.

Switch Expression

int integer = 1;
var obj =  switch(integer){
	case 1 -> "hello";
	case 4 -> 5.91;
	case 4 -> 5.91;
	default ->  Integer.valueOf(6);
};

This was the first, in the new industrious release cycle for JDK major versions, hereafter we get a brand new major release, every six months.

public class Demo12 {
    public static void main(String[] args){
        int integer = 1;
        var obj =  switch(integer){
            case 1 -> "hello";
            case 4 -> 5.91;
            default ->  Integer.valueOf(6);
        };
        System.out.println(obj+", world!");
    }

}

Output

hello, world!

Process finished with exit code 0

6. JDK 13

There wasn’t much here, except a preview of multiline text blocks, which I’ll deal with later in 15, and the cementing of the previously previewed Switch expressions.

You can also check our article about Migrating from Java 8 to Java 13.

7. JDK 14

Pattern Matching for ‘instanceof’, the only noteworthy language change in 14.

You can also check our article about What is new in Java 14.

A more concise version of the typical casting carry-on.

Pattern matching for instanceof

if (person instanceof woman woman) 
	woman.sprint();
else if(person instanceof Man man) 
	man.jump();

This removes the annoying casting that was necessary for such actions.

Alas, running the above will result in a runtime error, even today:

java: pattern matching in instanceof is a preview feature and is disabled by default.
(use –enable-preview to enable pattern matching in instanceof)

So, sadly, even with JDK15, pattern matching for instanceof, still is not officially available.

public class Demo14 {
    public Demo14() {
        Person declan = new Man();
        if (declan instanceof Woman woman)
            woman.sprint();
        else if(declan instanceof Man man)
            man.jump();

    }

    public interface Person{

    }

    class Man implements Person{
        public void jump(){
            System.out.println("jump");
        }
    }

    class Woman implements Person{
        public void sprint(){
            System.out.println("run");
        }
    }

    public static void main(String[] args){
        new Demo14();
    }
}

Output

jump

Process finished with exit code 0

8. JDK 15

This brings us up-to-date, and I encourage you to investigate this further, and not to let yourself fall so far behind in the future, especially now –since 12– that we are seeing a 6-month release cycle. My sources tell me that 17 is going to be epic.

8.1 Sealed Objects

As the name hints at, a sealed interface is pretty exclusive about whom may implement it.

Sealed interface

Public sealed interface FrontEndDeveloper permits Javascripter, Htmler

Sealed Classes or Interfaces have the power to disallow themselves to be implemented or overridden by any object, which is not one of a given list of types.

8.2 Text Blocks

It has been a long time coming, but text blocks are finally here.

Example of multi line text block variable definition.

Multiline Textblock

String multiLine = """

	bla bla bla
        bla bla bla
"""

If you upgrade to 15 today, you can start enjoying all the aforementioned features, but you’ll also be primed for future releases. Especially 17.

public class Demo15 {

    public static void main(String args[]){
        String multiline = """
                <html>
                    <body>
                        bla bla bla
                    </body>
                </html>
                """;

        System.out.println(multiline);


    }
//        java: sealed classes are a preview feature, and are disabled by default.
//        (use --enable-preview to enable pattern matching in instanceof)

    sealed class JvmDeveloper permits Javaer, Kotliner, Scalaer{

    }

    final class Javaer extends JvmDeveloper{}
    final class Kotliner extends JvmDeveloper{}
    final class Scalaer extends JvmDeveloper{}
    final class Python {}//extends JvmDeveloper{} compilation error
}

Output:

<html>
    <body>
        bla bla bla
    </body>
</html>


Process finished with exit code 0

9.  Download the source code 

The aforementioned, new features are available to play around within this sample project. Enjoy.

Download
You can download the full source code of this example here: Guide to Features Changes from Java 8 to Java 15

Declan Treanor

I am a senior Java developer with approximately 15 years' experience. I'm from Ireland but currently located in Germany (Hamburg), where I am working as a developer, predominantly using Java (with Spring), JavaScript and sometimes Kotlin. I enjoy the modern life of a techie; the collaborative nature, in which a techie can go about their business with the aid of some of the endless sources of help that are now available.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button