Friends of OpenJDK Today

The Evolution of Java: Challenging Stereotypes and Embracing Modernity

July 07, 2023

 

 

Author(s)

  • A N M Bazlur Rahman

    A N M Bazlur Rahman is a Software Engineer with over a decade of specialized experience in Java and related technologies. His expertise has been formally recognized through the prestigious ... Learn more

On a flight from Zurich to Toronto, I found myself in an engaging conversation with a fellow passenger. Among various topics, our conversation navigated toward our careers and, inevitably, as I am a Java developer, towards the world of Java.

This gentleman, having worked with Java some 15-20 years ago, was surprised to learn that I still actively use the language. "Isn't it slow?" he questioned. His question echoed a stereotype that I have often encountered, one that has stuck to Java from its earlier days.

However, this stereotype is not only outdated but also inaccurate. Java is no longer a slow language; in fact, it's considered one of the most performant languages, and in some scenarios, it even outperforms C++. In this article, we will tackle and dismantle such stereotypes as we explore the exciting evolution of Java.

Java: From Its Inception to Now

When James Gosling and his team at Sun Microsystems released Java in 1995, it was touted as a revolutionary step in the world of programming languages. Java's "write once, run anywhere" promise and its strong emphasis on security made it an immediate hit.

However, as the software landscape began to shift towards more dynamic and flexible languages, Java was somewhat left behind, earning a reputation as a verbose, old-fashioned language.

Today, thanks to ongoing and substantial upgrades to the language, Java is shedding these stereotypes. A slew of new features, alongside important improvements in existing ones, have kept Java not only relevant but also increasingly attractive for the modern developer.

Embracing Modernity: The New Features of Java

The modern versions of Java have brought in several compelling features that challenge the idea of Java as an old and rigid language.

Flexible Main Methods

 In a departure from the traditional 'public static void main(String[] args)', Java now allows additional entry points to an application, providing more flexibility and expressiveness in how programs are written and executed.

This new addition allows the classic "Hello, World!" program to be simplified to:

class HelloWorld { 
    void main() { 
        System.out.println("Hello, World!");
    }
}

We can further make the class declaration implicit. This further simplifies the "Hello, World!" program to:

void main() {
    System.out.println("Hello, World!");
}

If you are interested in reading more, read my news item published on infoQ: Breaking down Barriers: Introducing JDK 21’s Approach to Beginner-Friendly Java Programming

Records

With Records, Java provides a compact syntax for declaring classes which are supposed to be dumb data holders. This reduces the boilerplate code developers have to write, making the language learner more efficient. Consider the following class:

import java.util.Objects;

public final class User {
    private final Long id;
    private final String firstName;
    private final String lastName;

    public User(Long id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Long id() {
        return id;
    }

    public String firstName() {
        return firstName;
    }

    public String lastName() {
        return lastName;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (obj == null || obj.getClass() != this.getClass()) return false;
        var that = (User) obj;
        return Objects.equals(this.id, that.id) &&
                Objects.equals(this.firstName, that.firstName) &&
                Objects.equals(this.lastName, that.lastName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, firstName, lastName);
    }

    @Override
    public String toString() {
        return "User[" +
                "id=" + id + ", " +
                "firstName=" + firstName + ", " +
                "lastName=" + lastName + ']';
    }

}


This whole code can be written in one line with Record. 

public record User(Long id, String firstName, String lastName) {}

And that’s it.  

Sealed Classes 

Sealed classes (and interfaces) give developers more control over inheritance, providing a level of flexibility hitherto unseen in the Java world. 

If you’re interested in knowing more about the case of sealed classes, read this article: Java Sealed Classes: Building Robust and Secure Applications

Pattern Matching, Unnamed Patterns and Variables

The inclusion of these features ushers in a new level of expressiveness in the language, reducing the verbosity and making code easier to read and write.

For example, Unnamed pattern variables can be beneficial in switch statements where the same action is executed for multiple cases, and the variables are not used. Consider the following code: 

switch (b) {
    case Box(RedBall _), Box(BlueBall _) -> processBox(b);
    case Box(GreenBall _) -> stopProcessing();
    case Box(_) -> pickAnotherBox();
}

If you’re interested in knowing more about it, read this article: JEP 443: Unnamed Patterns and Variables Aims to Improve Java Code Readability

String Templates

Java developers can now enhance the language's string literals and text blocks with string templates that can produce specialized results by coupling literal text with embedded expressions and processors.

The aim of this new feature is to simplify the writing of Java programs, improve the readability of expressions that mix text and expressions, and enhance the security of Java programs that compose strings from user-provided values. Consider the following example: 

String name    = "Joan Smith";
String phone   = "555-123-4567";
String address = "1 Maple Drive, Anytown";

String json = STR."""
    {
        "name":    "\{name}",
        "phone":   "\{phone}",
        "address": "\{address}"
    }
    """;

This produces the following output.

| """
| {
|     "name":    "Joan Smith",
|     "phone":   "555-123-4567",
|     "address": "1 Maple Drive, Anytown"
| }
| """

Read the following infoQ item to know more about it: Java Gets a Boost with String Templates: Simplifying Code and Improving Security

Java's Handling of Concurrency

Java's improved handling of concurrency is another example of its modernization. The introduction of Virtual Threads (previously known as Project Loom) simplifies concurrent programming by making it easier to write, debug, profile, and maintain concurrent applications.

Additionally, Java's Structured Concurrency prevents common programming errors, making concurrent programming safer and more efficient.

To know more about read the following article I have written:

Unlocking High Performance with Modern Java Technologies

It's important to note that modern Java Virtual Machines (JVMs) have incorporated more efficient garbage collection algorithms, like the Garbage-First (G1) collector and the Z Garbage Collector (ZGC), designed to significantly reduce pause times and scale effectively. Furthermore, today's Just-In-Time (JIT) compilers have been greatly enhanced and are capable of generating highly efficient machine code. In certain instances, JIT-compiled code can surpass the performance of statically compiled code due to its ability to make optimizations based on real-time data.

JVMs have seen substantial advancements in efficiency through the application of progressive techniques such as adaptive optimization and speculative execution, which enhance performance. Additionally, Java's robust support for multi-threading ensures optimal utilization of modern multi-core processors. When appropriately designed, Java programs can exhibit high levels of concurrency and parallelism, yielding superior performance on contemporary hardware.

Java has been the foundation of countless high-performance applications and systems. This includes high-frequency trading systems, big data processing frameworks like Apache Hadoop and Apache Spark, as well as large-scale websites such as LinkedIn and eBay. This stands as a testament to its capabilities and versatility.



The Journey Ahead

While Java's transformation has been significant, it is far from over. With its robust ecosystem and the Java Community Process continually pushing for enhancements, the future is bright.

The Java we know today is not just a language capable of meeting the demands of modern software development but also one that is continually evolving to anticipate future needs.

In conclusion, Java is no longer your dad's language. It's a modern, expressive, and efficient tool that is more than capable of taking on the challenges of the contemporary development world.

The stereotypes have been challenged, and Java stands tall, embracing modernity.

Topics:

Related Articles

View All
  • “Foojay – All About Java and the OpenJDK” — I Programmer

    Tracking the OpenJDK is not an easy feat. It evolves rapidly under a release cycle of a new version every 6 months, hence there’s hoards of new features, changes and bug fixes.This is where foojay steps in, collecting all the relevant information.

    What was the alternative? A lot of manual searching. scouring disparate sources such as the OpenJDK mailing lists and official blog posts.

    So what does foojay do differently? It organizes information into distinct sections. All the OpenJDK and Java info you need, cleaned up, categorized and nicely presented under one roof.

    Read More
    November 02, 2020
  • 5 Things You Probably Didn’t Know About Java Concurrency

    Even while threads are helpful, they are dreadful to many developers. Here are five essential threading concepts for Java developers!

    Read More
    March 25, 2022
  • 7 Ways to Contribute to OpenJDK

    A great many developers today are employed working with OpenJDK. If OpenJDK is the background source for your livelihood, you might want to contribute to future development of the OpenJDK.

    There are many ways you can do this. In this article I outline 7 possibilities, ranging from minimal work (because you’re too busy to do much, but you’d like to do something) to intensive work (participating on OpenJDK development is everything you want to do, it’s more than a hobby, you want to contribute to the maximum extent possible).

    Read More
    November 18, 2020

Author(s)

  • A N M Bazlur Rahman

    A N M Bazlur Rahman is a Software Engineer with over a decade of specialized experience in Java and related technologies. His expertise has been formally recognized through the prestigious ... Learn more

Comments (3)

Your email address will not be published. Required fields are marked *

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Hari

Certainly, the language has evolved. However, this article should have emphasized more on exclusively performance aspects and benchmarks since the beginning of the article mentioned about perception of Java being a slow language

A N M Bazlur Rahman

Good point! I will perhaps write another article exclusively on performance aspects and benchmarks.

Harald

Nice new features and all very welcome. I wish there was an activity to fix the billon dollar mistake. @NotNull in a handful of tools are just 2nd choice to not-null built right into the type system.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard