The first time you look at a Java String Template, it feels right and wrong simultaneously.
String first = "John"; String last = "Smith"; String info = STR. "My first name is \{ first } and my last name is \{ last }" ;
Right because the result of the final statement is with the placeholders correctly evaluated and filled in. It feels wrong because of the strange new "STR." expression and the way the placeholders are escaped "\{ }"
However now that I have looked at it for some time, the reasoning does make sense and I have gotten used to the new syntax.
So let’s start with the motivation first, I will mostly follow the structure of the well-explained JEP that goes with this feature.
Motivation
10 plus 20 equals 30
int x = 10; int y = 20; String s = new StringBuilder() .append(x) .append(" plus ") .append(y) .append(" equals ") .append(x + y) .toString();
int x = 10; int y = 20; String s = STR. "\{ x } plus \{ y } equals \{ x + y }" ;
Workings
- the String template \{ x } plus \{ y } equals \{ x + y }, which is intuitive, the placeholder variables and expressions in a String template are escaped using \{ } syntax
- brand new expression syntax, STR.<string template>
- STR is the “Template Processor”, that returns the final processed string
String Template Processor
String first = "John"; String last = "Smith"; StringTemplate st = RAW. "My first name is \{ first } and my last name is \{ last }" ;
- fragments, which is [“My first name is” , “and my last name is” , “”] in the template above, the pieces of fixed text around the template placeholders
- values — which are the resolved placeholders, so in my example they are [“John”, “Smith”]
StringTemplate.Processor<String, RuntimeException> UPPER =
StringTemplate.Processor.of((StringTemplate st) -> {
StringBuilder sb = new StringBuilder();
Iterator<String> fragIter = st.fragments().iterator();
for (Object value : st.values()) {
sb.append(fragIter.next().toUpperCase());
sb.append(value);
}
sb.append(fragIter.next());
return sb.toString();
});