Modern Java for the Modern Age by Nick Maiorano



Java has been quietly re-invented for the modern age of computing. Yet many organizations are still stuck in yesterday’s Java and sitting out this revolution. Is your organization ready for the Modern Age of Java?

 23 years of Java

Earlier this year, Oracle released its 12th version of the Java language and platform with very little fanfare. Another routine release in its long 23-year history. This unremarkable marketing campaign sits in stark contrast to the importance of Java in the software development industry. Consider this: since 2001, Java’s been the first or second most popular programming language in the world [1]. What makes this a truly remarkable story is that Java has remained on top against a constantly shifting technological landscape. Think how different the software industry was back in 1996 when Java was initially released. It was the beginning of the mainstream Internet. A time before cloud computing, containers, JavaScript frameworks, the mobile web, NoSQL, multi-core processors, commodity hardware, DevOps, Agile, Y2K, Google, the iPhone, and REST-based microservices.  Java has even outlasted its own creator, Sun Microsystems, which could not find its way after the advent of hardware commoditization and was acquired by Oracle in 2009. (Java even continued its market dominance under Oracle’s stewardship.)

What can explain this? Was Java so well-designed that it became a timeless language, immune to technological changes in the software industry? No - Java has maintained its dominance in spite of change because it has always been absorbing new ideas. But this continued success has not been without unintended consequences. There have been so many changes over the years that two distinct styles of programming now exist within Java: Classic Java and Modern Java.
Let’s explorer these.

What is Classic Java?

Classic Java is the language that won the world over 23 years ago. It’s what made it rise to the top of the heap of languages. But it’s not without its flaws. Classic Java is characterized by boiler-plated code - the copy/pasting of code with small variances throughout the code base. Boiler-plating is not something developers aspire to but rather the outcome of a language that lacks expressiveness. Another side-effect of boiler-plating is verbosity. It too is a symptom of a language that lacks constructs. When a language is verbose, it takes more lines of code to achieve the same functionality than it normally should. This can hurt maintainability and diminish quality. Classic Java is also dominantly object-oriented in structure and imperative in algorithmic style. While both of these are still generally useful today, Classic Java is sorely lacking in the more modern styles of functional and declarative programming, which are better suited to solve today’s stringent software requirements. Classic Java developers are therefore more limited in the tools at their disposal. 
 
Finally, Classic Java also lacks constructs to design modular code and makes for slow start-up times and sluggish performance. The outcome is monolithic applications that are out of tune with today’s world of containers and serverless computing, which emphasize lean footprints and quick start ups.

What is Modern Java?

In 2014, Oracle released version 8 and took Java in an entirely new direction that had profound effects on coding style. With every subsequent release, Oracle has doubled-down and developed additional constructs that pushed Java even further in that direction. We are now firmly in the era of Modern Java. So what exactly is this? Modern Java is defined by these five programming paradigms and coding styles: functional programming, modular applications, reactive programming, fluent interface and stream-based programming. These tools are crucial in solving today’s computing challenges. Let’s look at how.
 
Functional programming is a paradigm that forces developers to think in terms of functions instead of classes. Functions are stateless and without side-effects. Avoiding state can lead to better software because managing state is notoriously difficult to get right, especially in high-performance, concurrent applications. Functional programming is also a natural fit for multi-core parallel programming and the best way to squeeze more performance out of modern CPUs.
 
Java 9 introduced modularity to the platform and allows Java applications to be deployed in smaller pieces. It also introduced the concept of linking, allowing a Java application to be deployed without a pre-installed JVM. That is, the application is bundled with its own streamlined JVM that contains only the bits it actually uses. Even the Java platform has been modularized making it aligned with today’s world of containers and serverless computing that play well with small footprints and quick start up times.
 
Reactive programming is another Java 9 addition and controls how applications can consume large sets of data without overwhelming the platform. Newly built JDK libraries such as HTTP 2 have been designed with reactive support to allow large chunks of data to be consumed with back-pressure for better flow control and less resource consumption.
 
Finally, Java Streams library allows algorithms to be coded declaratively meaning the developer specifies what they want, not how they want it. This improves code quality because all the plumbing code is handled by the library itself. The fluent interface style is just a way to express streams algorithm in one continuous line.
 
The disparities between Classic and Modern Java are quite striking. You can see the differences by comparing a simple algorithm written in both styles. The algorithm shown below reads a list of sentences and returns those that are palindromes. The first snippet is written in Classic Java while the second, in Modern Java, is almost a new language onto itself.
 

Figure 1: Find palindromes - Classic Java

 

//Find palindromes - Modern Java

private static List < String > findPalindromeModern(List < String > list) {
    BiFunction < String[], String, String[] > replacer =
        (h, s) - > {
            h[1] = h[1].replace(s, "");
            return h;
        };
    return list.stream().
    map(s - > {
        String[] h = new String[2];h[0] = h[1] = s;
        return h;
    }).
    map(h - > replacer.apply(h, " ")).
    map(h - > replacer.apply(h, ",")).
    map(h - > replacer.apply(h, "'")).
    map(h - > {
        h[1] = h[1].toLowerCase();
        return h;
    }).
    filter(h - > h[1].length() > 2).
    filter(h - > {
        int halfWay = h[1].length() / 2 - 1;
        return IntStream.rangeClosed(0, halfWay).
        allMatch(i - > h[1].charAt(i) == h[1].charAt(h[1].length() - i - 1));
    }).
    map(h - > h[0]).
    collect(Collectors.toList());
}

Figure 2: Find palindromes - Modern Java

Helping organizations

Today, 91% of organizations are still using versions of Java that are five or more years old [2]. Without upgrades, organizations are depriving themselves of hundreds of new features and improvements made during this time. What’s worse is that even within organizations that have upgraded to the latest version, many are still programming in the outdated Classic Java model. What’s holding back organizations?
 
Based on the experience in my own consulting practice, I can attest to the challenges they face.  Leveraging Modern Java requires more than just a Java upgrade. Developers must learn to think differently – and there is a steep learning curve. There are the new programming paradigms to understand and knowing how to apply these ideas is not trivial. 
 
ProTech Training can help your organization get the most out of your Java investment. ProTech offers a 3-day, Modern Java class that features all of the points discussed in this article. Attendees will learn all about functional programming and how it can be used effectively within Java. They will also learn about everything that Java has to offer in terms of concurrent and parallel programming. Plus, attendees will learn about modularity and how it can be used to build nimble applications aligned with today’s requirements. All of the new language syntax and constructs introduced in version 8 through 12 will be presented. But don’t worry, there are plenty of labs each day to ensure everyone attending will fully understand the material. This class is the best way to expose your Java developers to all of the newest, most-current and forward-thinking ideas in Java application development.
 
For more information, please consult the Modern Java course outline. You may also view our previously recorded Modern Java webinar.
 

Conclusion

Modern Java is an important evolution in the history of Java. And there are plenty more changes on the Java roadmap to ensure its dominance for decades to come. Let ProTech help you get the most out of your Java investment. Contact us today!
 
 
[1] Source: TIOBE Index, from a survey of 258 Turing-complete programming languages.
[2] As surveyed by Java Magazine published in October 2018

About the author

Nick Maiorano is the author of “Functional Java: A Guide to Lambdas and Functional Programming in Java 8” as well as the LinkedIn learning’s “Learning Java 9 Modularity”. He is a software architect and has been developing with Java since the 1990’s. He has also been a Java-based technology instructor at ProTech for four years.
 
 
Published May 15, 2019