What Future Java Might Look Like

Share this article

What Future Java Might Look Like

During the second week of November was Devoxx Belgium, Europe’s biggest Java conference, and as every year the community’s who’s-who showed up. One of them was Brian Goetz, Java Language Architect at Oracle, and he gave what I would consider the conference’s most thrilling talk: “Java Language and Platform Futures: A Sneak Peek”. In it he presented ideas that the JDK team is currently kicking around. And boy, is the pipeline full of great stuff! Java won’t look the same once it’s all out in the wild.

When will that be? Nobody knows. And that’s not nobody as in nobody outside of Oracle, that’s nobody as in nobody knows whether happy endings exist for arbitrary n. Brian went to great lengths to stress how very, very speculative all of the following is and how much things might evolve or simply get dropped. He went so far to let everyone in the audience sign an acknowledgment thereof (just mentally but still) and explicitly forbade any sensationalist tweets.

Well… first of all, this is no tweet and second of all, I wasn’t in that audience. So here we go! (Seriously though, take this as what it is: a glimpse into one of many, many possible futures.)

Crash Course

Before we go through the ideas one by one, let’s jump right in and have a look at what code might look like that uses all of the envisaged features. The following class is a simple linked list that uses two types of nodes:

  • InnerNodes that contain a value and link to the next node
  • EndNodes that only contain a value

One particularly interesting operation is reduce, which accepts a seed value and a BinaryOperator and applies it to the seed and all of the nodes’ values. This is what that might one day look like:

public class LinkedList<any T> {

    private Optional<Node<T>> head;

    // [constructors]
    // [list mutation by replacing nodes with new ones]

    public T reduce(T seed, BinaryOperator<T> operator) {
        var currentValue = seed;
        var currentNode = head;

        while (currentNode.isPresent()) {
            currentValue = operator.apply(currentValue, currentNode.get().getValue());
            currentNode = switch (currentNode.get()) {
                case InnerNode(_, var nextNode) -> Optional.of(nextNode);
                case EndNode(_) -> Optional.empty();
                default: throw new IllegalArgumentException();
            }
        }

        return currentValue;
    }

    private interface Node<any T> {
        T getValue();
    }

    private static class InnerNode<any T>(T value, Node<T> next) implements Node<T> { }

    private static class EndNode<any T>(T value) implements Node<T> { }

}

Wow! Hardly Java anymore, right?! Besides the omitted constructors there’s only code that actually does something – I mean, where’s all the boilerplate? And what if I told you that on top of that performance would be much better than today? Sounds like a free lunch, heck, like an entire free all-you-can-eat buffet!

Here’s what’s new:

  • The generic type argument is marked with any – what’s up with that?
  • Where are the type information for currentValue and currentNode in reduce?
  • That switch is almost unrecognizable.
  • The classes InnerNode and EndNode look, err, empty.

Let’s look at all the ideas that went into this example.

Data Objects

When was the last time you created a domain object that was essentially a dumb data holder, maybe with one or two non-trivial methods, that still required a hundred lines for constructors, static factory methods, accessors, equals, hashCode, and toString. (Right now, you say? Don’t worry, I don’t judge.) And while IDEs happily generate all of that, making typing it unnecessary even today, it is still code that needs to be understood (does the constructor do any validation?) and maintained (better not forget to add that new field to equals).

In an aggressive move to reduce boilerplate, the compiler might generate all of that stuff on the fly without us having to bend a finger!

Here’s what a user might look like:

public class User(String firstName, String lastName, DateTime birthday) { }

We can get everything else I mentioned above for free and only need to actually implement what’s non-standard (maybe users have an ID that alone determines equality, so we’d want an according equals implementation). Getting rid of all that code would be a great boost for maintainability!

Looking at the linked list example we can see that InnerNode and EndNode depend on this feature.

Value Types

When Java was created an arithmetic operation and a load from main memory took about the same number of cycles (speaking in magnitudes here). This changed considerably over the last 20 and more years to the point where memory access is about three magnitudes slower.

That all abstract Java types are objects, linked to each other via references, requires pointer hunting and makes the problem even worse. The benefits are that such types have identity, allow mutability, inheritance, and a couple of other things… which we don’t actually always need. This is very unsatisfactory and something needs to be done!

In comes Project Valhalla, as part of which value types are being developed as we speak. They can be summarized as self-defined primitives. Here’s a simple example:

value class ComplexNumber {

    double real;
    double imaginary;

    // constructors, getters, setters, equals, hashCode, toString
}

Looks like a regular class – the only difference is the keyword value in there.

Like primitives, value types incur neither memory overhead nor indirection. A self-defined ComplexNumber, like the one above with two double fields real and imaginary, will be inlined wherever it is used. Like primitives, such numbers have no identity – while there can be two different Double objects with value 5.0, there can’t be two different doubles 5.0. This precludes some of the things we like to do to objects: setting them to null, inheriting, mutating, and locking. In turn, it will only require the memory needed for those two doubles and an array of complex numbers will essentially be an array of real/imaginary pairs.

Like classes, value types can have methods and fields, encapsulate internals, use generics, and implement interfaces (but not extend other classes). Thus the slogan: “Codes like a class, works like an int.” This will allow us to no longer weigh an abstraction we would prefer against the performance (we imagine) we need.

Talking about performance, the advantages are considerable and can speed up just about any code. In a HashMap, for example, the nodes could become value types, speeding up one of Java’s most ubiquitous data structures. But this is not a low-level feature only hardcore library developers will want to use! It allows all of us to chose the right abstraction and inform the compiler as well as our colleagues that some of our objects in fact aren’t objects but values.

By the way, my personal guess is that the compiler would be just as helpful as with data objects and chip in constructors, getters, setters, etc.:

value class ComplexNumber(double real, double imaginary) { }

In case this wasn’t perfectly obvious: This is a deep change and interacts with basically everything:

  • the language (generics, wildcards, raw types, …)
  • the core libraries (collections, streams)
  • the JVM (type signatures, bytecodes, …)

So… where exactly in the linked list example do value types come in? Admittedly, they don’t play a big role. If I were clever enough to write a persistent data structure, the nodes could be value types (remember, they have to be immutable), which could be pretty interesting.

But there’s one possible value type in there: Optional. In Java 8 it is already marked as a value-based class, something that might one day become a value type or a wrapper thereof. This makes it flat and eliminates the memory indirection and possible cache miss it currently imposes.

Specialized Generics

With everybody and their dog creating primitive-like value types it becomes necessary to look at how they interact with parametric polymorphism. As you know, generics do not work for primitives – there can’t be an ArrayList<int>. This is already painful with eight primitives (see the primitive specializations of Stream or libraries like Trove) but becomes unbearable when developers can define more. If value types would have to be boxed to interact with generics (like primitives are today), their use would be fairly limited and they would be a non-starter.

So we want to be able to use generics with value types – and primitives can come along for the ride. In the end we not only want to instantiate an ArrayList<int> or ArrayList<ComplexNumber>, we also want it to be backed by an int[] or ComplexNumber[], respectively. This is called specialization and opens a whole new can of worms. (To take a good look at those worms, watch the talk “Adventures in Parametric Polymorphism”, which Brian gave at JVMLS 2016. That article also contains a list of talks you can watch if you want to get deeper.)

Code that wants to generify not only over reference types but also over value types must mark the respective type parameters with any. You can see that LinkedList, Node, and its implementations do exactly that. This means that in a LinkedList<int> the nodes would actually have int fields as opposed to the Object fields holding boxed Integers as would be the case with a LinkedList<Integer> nowadays.

binocular-future-of-java

More Type Inference

Java has done type inference since Java 5 (for type witnesses in generic methods) and the mechanism was extended in Java 7 (diamond operator), 8 (lambda parameter types), and 9 (diamond on anonymous classes). In Java X it might very well cover variable declarations. Brian’s example is this one:

// now
URL url = new URL("...")
URLConnectoin conn = url.openConnection();
Reader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

// maybe in the future
var url = new URL("...")
var conn = url.openConnection();
var reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

Here, the types of url, conn, and reader are perfectly obvious. As a consequence the compiler can infer them, making it unnecessary for us to specify them. In general, type inference can reduce boilerplate but also hide essential information. If you consider variable names to be more important than their types, you’ll like this as it aligns the names perfectly while throwing out redundant information.

Note that type inference is not dynamic typing – it’s still strong typing just with less typing (Brian’s pun – presumably intended). The type information will still end up in the bytecode and IDEs will also be able to show them – it’s just that we don’t have to write it out anymore.

An automatic process deducing types implies that code changes will change the outcome of that computation. While it is generally ok for a local variable to change its type (e.g. to its supertype), the same is not true for fields, method parameters or return values, etc. On the contrary, any change here could cause binary incompatibilities, which would lead to code compiled against an old version failing to link at runtime. Not good and hence forbidden.

So that only local variables’ types are inferred is more about protecting the ecosystem from unstable code than protecting developers from unreadable code.

Pattern Matching

Java’s current switch statement is pretty weak. You can use it for primitives, enums and strings but that’s it. If you want to do anything more complex, you either resort to if-else-if chains or, if you can’t get the Gang of Four book out of your head, the visitor pattern.

But think about it, there’s not really an intrinsic reason for these limitations. On a higher level a switch can be described to be using a variable to evaluate some conditions and choosing a matching branch, evaluating what it finds there – why should the variable’s type be so limited and the conditions only check equality? Come to think of it, why would the switch only do something as opposed to become something. Following this trail we end up with pattern matching, which has none of these limitations.

First of all, all kinds of variables could be allowed. Secondly, conditions could be much broader. They could, for example, check types or even deconstruct entire data objects. And last but not least, the whole switch should be an expression, evaluated to the expression in the branch of the matching condition.

Here are Brian’s examples:

// matching types
String formatted;
switch (constant) {
    case Integer i: formatted = String.format("int %d", i); break;
    case Byte b: //...
    case Long l: // ...
    // ...
    default: formatted = "unknown"
}

// used as an expression
String formatted = switch (constant) {
    case Integer i -> String.format("int %d", i);
    case Byte b: //...
    case Long l: // ...
    // ...
    default: formatted = "unknown"
}

// deconstructing objects
int eval(ExprNode node) {
    return switch (node) {
        case ConstantNode(var i) -> i;
        case NegNode(var node) -> -eval(node);
        case PlusNode(var left, var right) -> eval(left) + eval(right);
        case MulNode(var left, var right) -> eval(left) * eval(right);
        // ...
    }
}

For the linked list I also used it as an expression and to deconstruct the nodes:

currentNode = switch (currentNode.get()) {
    case InnerNode(_, var nextNode) -> Optional.of(nextNode);
    case EndNode(_) -> Optional.empty();
    default: throw new IllegalArgumentException();
}

Much nicer than what it would have to look like now:

if (currentNode.get() instanceof InnerNode) {
    currentNode = Optional.of(((InnerNode) currentNode.get()).getNext());
} else if (currentNode.get() instanceof EndNode) {
    currentNode = Optional.empty();
} else {
    throw new IllegalArgumentException();
}

(Yes, I know, this particular example could be solved with polymorphism.)

Summary

Again, wow! Data objects, value types, generic specialization, more type inference, and pattern matching – that’s a set of huge features the JDK team is working on. I can’t wait for them to come out! (By the way, while I presented all the features here, Brian provides so much more interesting background – you should definitely check out the entire talk.)

What do you think? Would you like to code in that Java?

Liked this post? Want to read more about Java’s present and future? Subscribe to our feed or newsletter.

Nicolai ParlogNicolai Parlog
View Author

Nicolai is a thirty year old boy, as the narrator would put it, who has found his passion in software development. He constantly reads, thinks, and writes about it, and codes for a living as well as for fun. Nicolai is the former editor of SitePoint's Java channel, writes The Java 9 Module System with Manning, blogs about software development on codefx.org, and is a long-tail contributor to several open source projects. You can hire him for all kinds of things.

nicolaipPattern MatchingProject AmberProject ValhallaTyping
Share this article
Read Next
Powerful React Form Builders to Consider in 2024
Powerful React Form Builders to Consider in 2024
Femi Akinyemi
Quick Tip: How to Animate Text Gradients and Patterns in CSS
Quick Tip: How to Animate Text Gradients and Patterns in CSS
Ralph Mason
Sending Email Using Node.js
Sending Email Using Node.js
Craig Buckler
Creating a Navbar in React
Creating a Navbar in React
Vidura Senevirathne
A Complete Guide to CSS Logical Properties, with Cheat Sheet
A Complete Guide to CSS Logical Properties, with Cheat Sheet
Ralph Mason
Using JSON Web Tokens with Node.js
Using JSON Web Tokens with Node.js
Lakindu Hewawasam
How to Build a Simple Web Server with Node.js
How to Build a Simple Web Server with Node.js
Chameera Dulanga
Building a Digital Fortress: How to Strengthen DNS Against DDoS Attacks?
Building a Digital Fortress: How to Strengthen DNS Against DDoS Attacks?
Beloslava Petrova
Crafting Interactive Scatter Plots with Plotly
Crafting Interactive Scatter Plots with Plotly
Binara Prabhanga
GenAI: How to Reduce Cost with Prompt Compression Techniques
GenAI: How to Reduce Cost with Prompt Compression Techniques
Suvoraj Biswas
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
Aurelio De RosaMaria Antonietta Perna
Quick Tip: How to Align Column Rows with CSS Subgrid
Quick Tip: How to Align Column Rows with CSS Subgrid
Ralph Mason
15 Top Web Design Tools & Resources To Try in 2024
15 Top Web Design Tools & Resources To Try in 2024
SitePoint Sponsors
7 Simple Rules for Better Data Visualization
7 Simple Rules for Better Data Visualization
Mariia Merkulova
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
SitePoint Team
Best Programming Language for AI
Best Programming Language for AI
Lucero del Alba
Quick Tip: How to Add Gradient Effects and Patterns to Text
Quick Tip: How to Add Gradient Effects and Patterns to Text
Ralph Mason
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Vultr
How to Optimize Website Content for Featured Snippets
How to Optimize Website Content for Featured Snippets
Dipen Visavadiya
Psychology and UX: Decoding the Science Behind User Clicks
Psychology and UX: Decoding the Science Behind User Clicks
Tanya Kumari
Build a Full-stack App with Node.js and htmx
Build a Full-stack App with Node.js and htmx
James Hibbard
Digital Transformation with AI: The Benefits and Challenges
Digital Transformation with AI: The Benefits and Challenges
Priyanka Prajapat
Quick Tip: Creating a Date Picker in React
Quick Tip: Creating a Date Picker in React
Dianne Pena
How to Create Interactive Animations Using React Spring
How to Create Interactive Animations Using React Spring
Yemi Ojedapo
10 Reasons to Love Google Docs
10 Reasons to Love Google Docs
Joshua KrausZain Zaidi
How to Use Magento 2 for International Ecommerce Success
How to Use Magento 2 for International Ecommerce Success
Mitul Patel
5 Exciting New JavaScript Features in 2024
5 Exciting New JavaScript Features in 2024
Olivia GibsonDarren Jones
Tools and Strategies for Efficient Web Project Management
Tools and Strategies for Efficient Web Project Management
Juliet Ofoegbu
Choosing the Best WordPress CRM Plugin for Your Business
Choosing the Best WordPress CRM Plugin for Your Business
Neve Wilkinson
ChatGPT Plugins for Marketing Success
ChatGPT Plugins for Marketing Success
Neil Jordan
Managing Static Files in Django: A Comprehensive Guide
Managing Static Files in Django: A Comprehensive Guide
Kabaki Antony
The Ultimate Guide to Choosing the Best React Website Builder
The Ultimate Guide to Choosing the Best React Website Builder
Dianne Pena
Exploring the Creative Power of CSS Filters and Blending
Exploring the Creative Power of CSS Filters and Blending
Joan Ayebola
How to Use WebSockets in Node.js to Create Real-time Apps
How to Use WebSockets in Node.js to Create Real-time Apps
Craig Buckler
Best Node.js Framework Choices for Modern App Development
Best Node.js Framework Choices for Modern App Development
Dianne Pena
SaaS Boilerplates: What They Are, And 10 of the Best
SaaS Boilerplates: What They Are, And 10 of the Best
Zain Zaidi
Understanding Cookies and Sessions in React
Understanding Cookies and Sessions in React
Blessing Ene Anyebe
Enhanced Internationalization (i18n) in Next.js 14
Enhanced Internationalization (i18n) in Next.js 14
Emmanuel Onyeyaforo
Essential React Native Performance Tips and Tricks
Essential React Native Performance Tips and Tricks
Shaik Mukthahar
How to Use Server-sent Events in Node.js
How to Use Server-sent Events in Node.js
Craig Buckler
Five Simple Ways to Boost a WooCommerce Site’s Performance
Five Simple Ways to Boost a WooCommerce Site’s Performance
Palash Ghosh
Elevate Your Online Store with Top WooCommerce Plugins
Elevate Your Online Store with Top WooCommerce Plugins
Dianne Pena
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Dianne Pena
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
Vultr
Enhance Your React Apps with ShadCn Utilities and Components
Enhance Your React Apps with ShadCn Utilities and Components
David Jaja
10 Best Create React App Alternatives for Different Use Cases
10 Best Create React App Alternatives for Different Use Cases
Zain Zaidi
Control Lazy Load, Infinite Scroll and Animations in React
Control Lazy Load, Infinite Scroll and Animations in React
Blessing Ene Anyebe
Building a Research Assistant Tool with AI and JavaScript
Building a Research Assistant Tool with AI and JavaScript
Mahmud Adeleye
Understanding React useEffect
Understanding React useEffect
Dianne Pena
Web Design Trends to Watch in 2024
Web Design Trends to Watch in 2024
Juliet Ofoegbu
Building a 3D Card Flip Animation with CSS Houdini
Building a 3D Card Flip Animation with CSS Houdini
Fred Zugs
How to Use ChatGPT in an Unavailable Country
How to Use ChatGPT in an Unavailable Country
Dianne Pena
An Introduction to Node.js Multithreading
An Introduction to Node.js Multithreading
Craig Buckler
How to Boost WordPress Security and Protect Your SEO Ranking
How to Boost WordPress Security and Protect Your SEO Ranking
Jaya Iyer
Understanding How ChatGPT Maintains Context
Understanding How ChatGPT Maintains Context
Dianne Pena
Building Interactive Data Visualizations with D3.js and React
Building Interactive Data Visualizations with D3.js and React
Oluwabusayo Jacobs
JavaScript vs Python: Which One Should You Learn First?
JavaScript vs Python: Which One Should You Learn First?
Olivia GibsonDarren Jones
13 Best Books, Courses and Communities for Learning React
13 Best Books, Courses and Communities for Learning React
Zain Zaidi
5 jQuery.each() Function Examples
5 jQuery.each() Function Examples
Florian RapplJames Hibbard
Implementing User Authentication in React Apps with Appwrite
Implementing User Authentication in React Apps with Appwrite
Yemi Ojedapo
AI-Powered Search Engine With Milvus Vector Database on Vultr
AI-Powered Search Engine With Milvus Vector Database on Vultr
Vultr
Understanding Signals in Django
Understanding Signals in Django
Kabaki Antony
Why React Icons May Be the Only Icon Library You Need
Why React Icons May Be the Only Icon Library You Need
Zain Zaidi
View Transitions in Astro
View Transitions in Astro
Tamas Piros
Getting Started with Content Collections in Astro
Getting Started with Content Collections in Astro
Tamas Piros
What Does the Java Virtual Machine Do All Day?
What Does the Java Virtual Machine Do All Day?
Peter Kessler
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Mayank Singh
Layouts in Astro
Layouts in Astro
Tamas Piros
.NET 8: Blazor Render Modes Explained
.NET 8: Blazor Render Modes Explained
Peter De Tender
Mastering Node CSV
Mastering Node CSV
Dianne Pena
A Beginner’s Guide to SvelteKit
A Beginner’s Guide to SvelteKit
Erik KückelheimSimon Holthausen
Brighten Up Your Astro Site with KwesForms and Rive
Brighten Up Your Astro Site with KwesForms and Rive
Paul Scanlon
Which Programming Language Should I Learn First in 2024?
Which Programming Language Should I Learn First in 2024?
Joel Falconer
Managing PHP Versions with Laravel Herd
Managing PHP Versions with Laravel Herd
Dianne Pena
Accelerating the Cloud: The Final Steps
Accelerating the Cloud: The Final Steps
Dave Neary
An Alphebetized List of MIME Types
An Alphebetized List of MIME Types
Dianne Pena
The Best PHP Frameworks for 2024
The Best PHP Frameworks for 2024
Claudio Ribeiro
11 Best WordPress Themes for Developers & Designers in 2024
11 Best WordPress Themes for Developers & Designers in 2024
SitePoint Sponsors
Top 10 Best WordPress AI Plugins of 2024
Top 10 Best WordPress AI Plugins of 2024
Dianne Pena
20+ Tools for Node.js Development in 2024
20+ Tools for Node.js Development in 2024
Dianne Pena
The Best Figma Plugins to Enhance Your Design Workflow in 2024
The Best Figma Plugins to Enhance Your Design Workflow in 2024
Dianne Pena
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Christopher Collins
Build Your Own AI Tools in Python Using the OpenAI API
Build Your Own AI Tools in Python Using the OpenAI API
Zain Zaidi
The Best React Chart Libraries for Data Visualization in 2024
The Best React Chart Libraries for Data Visualization in 2024
Dianne Pena
7 Free AI Logo Generators to Get Started
7 Free AI Logo Generators to Get Started
Zain Zaidi
Turn Your Vue App into an Offline-ready Progressive Web App
Turn Your Vue App into an Offline-ready Progressive Web App
Imran Alam
Clean Architecture: Theming with Tailwind and CSS Variables
Clean Architecture: Theming with Tailwind and CSS Variables
Emmanuel Onyeyaforo
How to Analyze Large Text Datasets with LangChain and Python
How to Analyze Large Text Datasets with LangChain and Python
Matt Nikonorov
6 Techniques for Conditional Rendering in React, with Examples
6 Techniques for Conditional Rendering in React, with Examples
Yemi Ojedapo
Introducing STRICH: Barcode Scanning for Web Apps
Introducing STRICH: Barcode Scanning for Web Apps
Alex Suzuki
Using Nodemon and Watch in Node.js for Live Restarts
Using Nodemon and Watch in Node.js for Live Restarts
Craig Buckler
Task Automation and Debugging with AI-Powered Tools
Task Automation and Debugging with AI-Powered Tools
Timi Omoyeni
Quick Tip: Understanding React Tooltip
Quick Tip: Understanding React Tooltip
Dianne Pena
12 Outstanding AI Tools that Enhance Efficiency & Productivity
12 Outstanding AI Tools that Enhance Efficiency & Productivity
Ilija Sekulov
React Performance Optimization
React Performance Optimization
Blessing Ene Anyebe
Introducing Chatbots and Large Language Models (LLMs)
Introducing Chatbots and Large Language Models (LLMs)
Timi Omoyeni
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Ampere Computing
Scale Your React App with Storybook and Chromatic
Scale Your React App with Storybook and Chromatic
Daine Mawer
10 Tips for Implementing Webflow On-page SEO
10 Tips for Implementing Webflow On-page SEO
Milan Vracar
Create Dynamic Web Experiences with Interactive SVG Animations
Create Dynamic Web Experiences with Interactive SVG Animations
Patricia Egyed
Get the freshest news and resources for developers, designers and digital creators in your inbox each week