Java 12 String API Updates

Following the unexpected success of my previous article about Java 11 String API, time to have a look at new API methods coming to String in JDK 12 release to be out on 19.03.2019.

Most interesting ones are related directly to JEP-334: JVM Constants API.

String#indent(int)

As simple as it sounds, that method allows us to adjust the indentations of String instances.

Mind the gap(pun intended):

String result = "foo

bar

bar2".indent(4); System.out.println(result); // foo // bar // bar2

System.out.println(result.length()); // 25

This one is supposed to complement JEP-326 – Raw String Literals that was withdrawn from JDK 12 already due to controversies surrounding implementation details.

String#transform(Function)

A little method introduced by JDK-8203442 that feeds the provided function with a particular String instance as input and returns output returned by that function.

So, let’s have a look at an example:

var result = "foo".transform(input -> input + " bar"); System.out.println(result); // foo bar

We can also chain these if we really feel like we need to:

var result = "foo" .transform(input -> input + " bar") .transform(String::toUpperCase) System.out.println(result); // FOO BAR

However, it doesn’t mean that we should.

The implementation (at the point of writing, however, I’d not expect this one to change) is as straightforward as it gets:

public <R> R transform(Function<? super String, ? extends R> f) { return f.apply(this); }

At some point in time, that method was supposed to be called map() but this idea was abandoned I believe it’s a right decision since one can expect monadic-like semantics when using similarly called methods.

In this case, it’s just a convenience method.

String#describeConstable

And lastly, a quite interesting method from a newly introduced interface java.lang.constant.Constable which I will cover in depth in a dedicated article but to not leave you empty handed – it’s used for marking types that are constable(duh!), which means a type whose values are constants that can be represented in the constant pool as defined in JVMS 4.4 The Constant Pool.

In String’s case, that’s trivial since the nominal descriptor for String instance… is the instance itself:

/** * Returns an {@link Optional} containing the nominal descriptor for this * instance, which is the instance itself. * * @return an {@link Optional} describing the {@linkplain String} instance * @since 12 */ @Override public Optional<String> describeConstable() { return Optional.of(this); }

In most cases, don’t expect to call this one manually on String instances often.

String#resolveConstantDesc(MethodHandles$Lookup)

The other method, supporting low-level JEP-334: JVM Constants API, that you won’t be calling manually often – this time, coming from java.lang.constant.ConstantDesc which marks a loadable constant value, as defined in JVMS 4.4 The Constant Pool.

And again, in String’s cases that would just mean… returning itself:

/** * Resolves this instance as a {@link ConstantDesc}, the result of which is * the instance itself. * * @param lookup ignored * @return the {@linkplain String} instance * @since 12 */ @Override public String resolveConstantDesc(MethodHandles.Lookup lookup) { return this; }

Stay tuned for a dedicated article about JVM Constants API.



