-
Notifications
You must be signed in to change notification settings - Fork 65
String Templating
StringFormat
supports string templating.
For the most common use case, you can define a string template to be reused througout a class:
private static final StringFormat BUCKET_RESOURCE_NAME =
new StringFormat("projects/{project}/locations/{location}/buckets/{bucket}");
...
// 200 lines away
String bucketResourceName = BUCKET_RESOURCE_NAME.format(projectId, location, bucket);
Or a public template across files:
public final class ResourceNameFormats {
public static final String BUCKET_FORMAT =
"projects/{project}/locations/{location}/buckets/{bucket}";
}
// Another package, another file
String bucketResourceName =
StringFormat.using(ResourceNameFormats.BUCKET_FORMAT, projectId, location, bucket);
StringFormat
also supports templating into non-String types, as inspired by JEP 459. It allows extensions to be built with custom interpolation rules to build into any arbitrary type.
For example the SafeQuery
class is a SQL templating engine built on top of StringFormat
. It guards against SQL injection, and at the same time the ErrorProne compile-time checks for correct argument ordering works on all these extensions:
SafeQuery.of("select {columns} from tbl where id = '{id}'", columns, userId)
JEP 459 and following revisions will add string templating to the language sooner or later.
The syntax will likely look like "Hello \{audience}, today is \{day}."
There may be slight variants to the placeholder whether it's \{placeholder}
, or ${placeholder}
or perhaps there is a prefix ahead of the double quote. And there may be a "processor", or not. Hard to say.
But one thing is certain: we'll be able to interpolate variables into strings.
That begs the question: if official templating is so close, is StringFormat.Template
still needed?
It looks like the main benefit of StringFormat
template won't be provided by the JEP. That is: to be able to reuse a template with compile-time protection against incorrect placeholder order.
With the JEP, you can't define a template and reuse it in different places. The placeholders must be variables in scope. You could wrap them in methods with parameters. But then you risk the parameters being passed in the wrong order. If your template has many placeholders, it becomes the method with many parameters anti-pattern.