It was recently proposed that the Java preview feature Raw String Literals (JEP 326) be removed from JDK 12 and it is now official that the preview feature will be removed (version 25 of Java SE 12 [JSR 386] removes it). Several methods had been added to the JDK String class to support this feature. Those methods that were added to versions of the JDK prior to JDK 12 [such as String::lines] are likely to remain available even after the raw string literals preview feature has been removed. However, it has already been decided that one method added to String
in JDK 12 (String::align
) should be removed from JDK 12 as part of removing raw string literals. The method String::transform was added to JDK 12 and the remainder of this post looks at String::transform
, as currently implemented in JDK 12, in more detail and discusses why its already controversial short history implies that it could be a potential candidate for removal along with raw string literals.
The current String::transform
implementation has been available in JDK 12 Early Access Builds since Build 22 (Build 24 [15 December 2018] is latest available build as of this writing) and was introduced via JDK-8203442 ("String::transform").
There was quite a bit of discussion related to this method being added to the JDK. The following bullets outline key discussion points.
- Jim Laskey wrote that the "originating goal" of
String::transform
was to "allow custom alignment methods for those developers not satisfied withString::align()
"String::align
has been added to and then removed from JDK 12 since that post onString::transform
.
- Other messages further describe the motivation for, intent of, and benefits of
String::transform
:- Rémi Forax wrote, "...it's nice to be able to be able to write code fluently from left to right..."
- Jim Laskey wrote, "String::transform was intended to facilitate custom manipulation (alignment) of raw string literals, in the most string generalized way."
- The "Description" of JDK-8203442 states, "The String::transform instance method allows the application of a lambda function to a string."
- JDK-8203703 supplies examples to illustrate that "...steps can be discerned more clearly" with String::transform than with static methods in which the "reader is forced to interpret portions of the expression from the inside out."
String::transform
originally returnedString
, but then was changed to returnObject
and Jim Laskey wrote about that change, "'transform' became generic when the case was made that other types might also be relevant." He concluded, "I might be led back to just supportingString
."- The naming of
String::transform
has been challenging with some of the following names proposed (listed in alphabetic order):- "apply"
- "applyMutation" (used by AWS SDK, but not everyone likes it)
- "asInputTo"
- "chain"
- "map" (was named this temporarily but there were concerns)
- "process"
- "with"
- Rémi Forax has written that "more variants (
transformToInt
,transformToLong
,transformToDouble
) [are needed] to be useful." - Brian Goetz has described why the current plan is to implement this functionality via the method
String::transform
rather than an operator such as|>
. - Stuart Marks has written that "this particular decision [
String::transform
] sets a precedent for the use of the name 'transform' for methods that do similar things on other classes" and references JDK-8140283 and JDK-8214753:- JDK-8140283 proposes the addition of the "
chain
" method for Stream and Optional to "mitigate" the "disrupt[ion of] the linear flow of the pipeline stages" when using methods that acts upon aStream
orOptional
and return something that is itself "chainable"). - JDK-8214753 proposes the addition of "
Optional::transform
" that would allow for "an arbitrary operation on anOptional
."
- JDK-8140283 proposes the addition of the "
- There was some confusion and consternation related to how
String::transform
was added to OpenJDK 12, but Stuart Marks's message summarizes the events leading to the addition of this method.- A particularly interesting sentence in Marks's message states (I have added the emphasis): "While this API point stands on its own, this is really part of Jim's RSL work which includes several API additions to String, and which will likely have a significant effect on how
String
literals are used in Java code."
- A particularly interesting sentence in Marks's message states (I have added the emphasis): "While this API point stands on its own, this is really part of Jim's RSL work which includes several API additions to String, and which will likely have a significant effect on how
- Tomasz Linkowski has pointed out that it's likely that
String::transform
(and any similar method added toStream
) will get used in select cases where there are easier ways to do the same thing already without the new method. The examples he provides of potential misuse ofString::transform
are "string.transform(String::toLowerCase)
" and "stream.chain(s->s.map(mapper))
".
Two online examples demonstrate how String::transform
might be used in its most common use cases:
- JDK-8203703 ("String::transform") provides a "Solution" example that demonstrates how
String::transform
can improve code readability by allowing for operations acting onString
s to be read in order from left-to-right rather than being read "from the inside out." - A message on the core-libs-dev mailing list provides an example of using
String::transform
to convert aString
into an instance of a class other thanString
.
Stephen Colebourne asked the same question I was wondering when I read that raw string literals were to be removed from JDK 12: "Is String::transform
going to be removed as well given the removal of raw strings and its controversial nature?" Although I have not seen anything authoritative and definitive regarding whether String::transform
will remain in JDK 12, there are three pieces of evidence that lead me to think it will be staying.
- I have not seen anything saying that
String::transform
, which is already in JDK 12 as of Early Access Build 22, is to be removed. There are issues written to remove compiler support associated with raw string literals and even to remove another String method (String::align
), but I'm not aware of a similar issue written forString::transform
. - It has been stated that while
String::transform
was added as part of the raw string literal work, it was also stated thatString::transform
"stands on its own." - The two examples I cited earlier on how to use this method do not rely on or require raw string literals. In other words, the method can be used regardless of the presence or absence of raw string literals.
String::transform
has not been around for a long time (less than one year), but it already has significant history. The method is available currently in JDK 12 (since Early Access Build 22) and I suspect it will remain part of String
's API despite the removal of raw string literals from JDK 12.
1 comment:
JDK 12 Early Access Build 28 includes a bug fix related to String::transform (JDK-8215112), but it's only an addition to that method's Javadoc comment to add that "Any exception thrown by {@code f()} will be propagated to the caller." The full list of changes for JDK 12 Early Access Build 28 is available and shows fixes for related issues "8215489: Remove String::align" and "8215493: String::indent inconsistency with blank lines".
Post a Comment