Looking at Java 21: The Little Things
Besides the “big” features that often aggregate under well-known project names, like “Amber”, “Loom”, or “Panama”, there are many little things in every release that are easy to miss. These API and tool improvements might not be as visible as other features, as they’re not represented by a JEP. That doesn’t mean we don’t need to know about them.
Let’s take a look at some of the “other” changes that Java 21 gave us!
Table of Contents
Working with Strings and Characters
Java’s new String
templates might have been the show-stealer of this release in regards to String
, but there are a few more additions the String
type and adjacent ones.
String#indexOf
We already had 4 different indexOf
methods available to find the index of an int
or String
argument, starting at the beginning or a given index.
Java 21 added another variant for both finding either an int
or String
by providing an end-index in addition to a beginning one:
Be aware that the beginIndex
is inclusive, but the endIndex
is exclusive.
In my opinion, they should’ve named them accordingly, as they did with IntStream.rangeClosed
for example.
String#splitWithDelimiters
The two split
methods got a new acquaintance that works a little differently, hence the more expressive name:
The splitting itself is like you would expect it from knowing split(String, int)
, but the returned String[]
contains the split parts AND the delimiters:
As you can see in the actual source code and the API note in the documentation, besides from an optimization for one or two character non-regexes, the call is equivalent to Pattern.compile(regex).splitWithDelimiters(str, limit)
StringBuilder and StringBuffer
Both types received new convenience methods called repeat
for both CharSequence
and int
arguments:
They all do what it says on the carton:
Identifying Emojis
Over the years, Emojis gained more and more properties, like different color shades and combined presentations.
To make identification easier, the Character
type gained 6 new static
methods:
Complementing these identification methods, new predefined character groups are available in patterns, too:
\p{IsEmoji}
\p{IsEmoji_Presentation}
\p{IsEmoji_Modifier}
\p{IsEmoji_Modifier_Base}
\p{IsEmoji_Component}
What these properties actually mean is defined in the “Unicode Technical Standard #51.
Math-related Additions
Clamping, a common use case, was simplified by adding 4 static
method clamp
for number primitives to ensure a value
is in between or equal min
and max
:
The first method returns an int
to do double duty, providing a way to clamp long
and a (casted) int
into an int
-based range.
All methods are also available on the StrictMath
type.
HttpClient is an AutoClosable (and more)
The java.net.http.HttpClient
now implements AutoClosable
, making it usable in a try-with-resources
block.
There are also 5 new related methods:
Instances obtained via HttpClient.newHttpClient()
or HttpClient.newBuilder()
provide best-effort implementations of these methods.
To learn more about them, check out the “Implementation Note” in the official documentation.
Improved Sleep Quality
Thread.sleep(long millis, int nanos)
can now perform sub-millisecond sleeps on POSIX platforms.
Before, non-zero arguments for nanos
were rounded up to a full millisecond before.
Be aware that the actual precision still depends on the underlying system!
JDK Tool Access in JShell
The JShell is one of my favorite tool added to the JDK in version 9, as it provides a quick and easy way to check out code snippets and verify behavior.
To set it up to your particular needs, you can use “start-up scripts”. Before the release of Java 21, there were 3 start-up scripts available:
DEFAULT
- loaded if no start-up script is specified.
JAVASE
- imports a lot more packages.
PRINTING
- like default, but adds
print
convenience methods.
Now, there’s a new one available: TOOLING
This start-up script introduces various Java tools as methods right into JShell:
The also available method tools()
lists all available Java tools.
For example, to introspect the Bytecode of a type, you can now do:
Be aware that starting JShell only with TOOLING
will lack the common default imports, so I suggest always to load DEFAULT
, too:
Conclusion
These were just a few of the many changes flying under the radar as they don’t have a JEP attached to them.
Nevertheless, it’s always a good idea to check out the “little things”, too, as they can affect such basic types like String
and might contain a hidden gem.
To check out all changes of Java 21, regardless of whether it is a JEP or “just” a ticket, see the official release notes.
If you’re interested in a more technical comparison, I recommend the Java Version Almanac, which compares the API of different versions to highlight all changes, additions, and removals.
Resources
Looking at Java 21
- Intro
- String Templates (JEP 430)
- Simpler Main Methods and Unnamed Classes (JEP 445)
- Sequenced Collections (JEP 431)
- Scoped Values (JEP 446)
- Switch Pattern Matching (JEP 441)
- Feature Deprecations (JEP 449, 451)
- Record Pattern Matching (JEP 440)
- Generational ZGC (JEP 439)
- Virtual Threads (JEP 444)
- The Little Things