Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8296302

JEP 430: JLS Changes for String Templates (Preview)

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 21
    • specification
    • None
    • source
    • minimal
    • Hide
      This is part of the preview feature String Templates. The new APIs do not conflict with existing APIs or behaviour and do not require any class file changes.

      The change to automatically import the static field `STR` in every Java program is not 100% source compatible. Two examples, each of which is expected to be extremely rare:

      1. Suppose a program previously brought the simple name `STR` into scope via an explicit static-import-on-demand declaration `import static foo.bar.*;` (where the class `foo.bar` declares a static field `STR`). The explicit declaration will be shadowed by the automatic single-static-import declaration `import static java.lang.template.StringTemplate.STR;`, such that the simple name `STR` now refers to a `StringProcessor` and not whatever `foo.bar.STR` is. The program will have to be changed to use the qualified name `foo.bar.STR` -- and depending on what else is in class `foo.bar`, the explicit `import static foo.bar.*;` may now be redundant.

      2. Suppose a program previous brought the simple name `STR` into scope via an explicit single-static-import declaration `import static foo.bar.STR;`. Any use of the simple name `STR` will now produce a compile-time error. This is due to ambiguity: the program also declares `import static java.lang.template.StringTemplate.STR;` and neither declaration of the field `STR` shadows the other. The program will have to be changed to use the qualified name `foo.bar.STR` or `java.lang.template.StringTemplate.STR` as appropriate. The explicit `import static foo.bar.STR;` is effectively redundant.
      Show
      This is part of the preview feature String Templates. The new APIs do not conflict with existing APIs or behaviour and do not require any class file changes. The change to automatically import the static field `STR` in every Java program is not 100% source compatible. Two examples, each of which is expected to be extremely rare: 1. Suppose a program previously brought the simple name `STR` into scope via an explicit static-import-on-demand declaration `import static foo.bar.*;` (where the class `foo.bar` declares a static field `STR`). The explicit declaration will be shadowed by the automatic single-static-import declaration `import static java.lang.template.StringTemplate.STR;`, such that the simple name `STR` now refers to a `StringProcessor` and not whatever `foo.bar.STR` is. The program will have to be changed to use the qualified name `foo.bar.STR` -- and depending on what else is in class `foo.bar`, the explicit `import static foo.bar.*;` may now be redundant. 2. Suppose a program previous brought the simple name `STR` into scope via an explicit single-static-import declaration `import static foo.bar.STR;`. Any use of the simple name `STR` will now produce a compile-time error. This is due to ambiguity: the program also declares `import static java.lang.template.StringTemplate.STR;` and neither declaration of the field `STR` shadows the other. The program will have to be changed to use the qualified name `foo.bar.STR` or `java.lang.template.StringTemplate.STR` as appropriate. The explicit `import static foo.bar.STR;` is effectively redundant.
    • Language construct
    • SE

      This is the CSR for the Java Language Specification changes of JEP-430 String Templates (Preview)

      Summary

      Enhance the Java programming language with string templates. String templates complement Java's existing string literals and text blocks by coupling literal text with embedded expressions and processors to produce specialized results. This is a preview language feature and API.

      Problem

      Developers routinely compose strings from a combination of literal text and expressions. Java provides several mechanisms for string composition, though unfortunately all have drawbacks.

      • String concatenation with the + produces hard-to-read code:

        String s = x + " plus " + y + " equals " + (x + y);
      • StringBuilder is verbose:

        String s = new StringBuilder()
                     .append(x)
                     .append(" plus ")
                     .append(y)
                     .append(" equals ")
                     .append(x + y)
                     .toString();
      • String::format and String::formatted separate the format string from the parameters, inviting arity and type mismatches:

        String s = String.format("%2$d plus %1$d equals %3$d", x, y, x + y);
        String t = "%2$d plus %1$d equals %3$d".formatted(x, y, x + y);
      • java.text.MessageFormat requires too much ceremony and uses an unfamiliar syntax in the format string:

        MessageFormat mf = new MessageFormat("{0} plus {1} equals {2}");
        String s = mf.format(x, y, x + y);

      The convenience of interpolation also has a downside: It is easy to construct strings that will be interpreted by other systems but which are dangerously incorrect in those systems.

      Strings that hold SQL statements, HTML/XML documents, JSON snippets, shell scripts, and natural-language text all need to be validated and sanitized according to domain-specific rules. Since the Java programming language cannot possibly enforce all such rules, it is up to developers using interpolation to validate and sanitize. Typically, this means remembering to wrap embedded expressions in calls to escape or validate methods, and relying on IDEs or static analysis tools to help to validate the literal text.

      Interpolation is especially dangerous for SQL statements because it can lead to injection attacks. The prevalence of injection attacks as led to organizations dedicated to preventative measures, ex., [OWASP]https://en.wikipedia.org/wiki/OWASP.

      Solution

      JEP-430 String Templates (Preview) introduces string templates which will allow users to inject values into a String in situ. The use of string templates versus string interpolation allows for a richer feature that, in addition to composition, allows validation and non-string result transformations.

      For the purposes of a terminology overview, the statement;

          String s = x + " plus " + y + " equals " + (x + y);

      can be equivalently expressed using the template expression;

          String s = STR."\{x} plus \{y} equals \{x + y}";

      The template expression is composed of two parts, the template processor and the template argument separated with a dot.

      The template processor is an expression that when evaluated produces an instance of a class implementing the ValidatingProcessor interface. This processor instance receives the details of the template argument by way of the processor's process method. The processor uses this method to validate the details of the argument and then produce a result. It is through this process method that the string templates feature provides a more secure and richer mechanism than string interpolation.

      The automatically imported STR template processor used in the example, provides the equivalence of string interpolation.

      The template argument can be a string literal, a text block or a template. A template has the appearance of a string literal or text block, except the literal's content incorporates one or more embedded expressions distinguished from the literal parts of the content by bracketing with \{and }. An embedded expression can be any Java expression.

      Once the template argument and embedded expressions are evaluated, the details of the template argument are incorporated into an instance of class that implements the StringTemplate interface. The details are represented using two lists, a list of string fragments - the characters outside of the embedded expressions and a list of values - the results of evaluating the embedded expressions.

      The template argument details for the example would be a fragments list equivalent to List.of("", " plus ", " equals ", "") and values list equivalent to List.of(x, y, x + y). Note that all fragments are provided even if empty.

      Further details can be found in the JEP JEP-430 String Templates (Preview) and the enclosed Java Language Specification edits.

      Specification

      Details of the Java Language Specification edits are enclosed.

      Changes described above are only available with --enable-preview including the introduction of Template Expressions, new runtime APIs and the automatic import of java.lang.template.StringTemplate.STR. No class file changes are required.

            jlaskey Jim Laskey
            jlaskey Jim Laskey
            Gavin Bierman
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: