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

JDK 11 invokedynamic-based string concatenation produces different result than JDK 8

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 11, 17
    • tools
    • None
    • generic
    • generic

      This is a small semantic change of the String "+" operator caused by the invokedynamic-based string concatenation (JDK-8085796). I am not aware that it was mentioned anywhere (like in the "risk" section of JEP 280), so I want to document it.

      The following application prints a different result when compiled with JDK 8 and JDK 11:

      public class HelloWorld {
          public static void main(String[] args) {
              Handler h = new Handler();
              System.out.println(h + h.incrementAndGet() + h);

              h = new Handler();
              System.out.println(new StringBuilder().append(h).append(h.incrementAndGet()).append(h).toString());
          }
      }

      class Handler {
          int state;
          
          String incrementAndGet() {
              state++;
              return String.valueOf(state);
          }
          
          @Override
          public String toString() {
              return incrementAndGet();
          }
      }


      When compiled with JDK 8, using the "+" operator leads to the same bytecode as the explicit usage of StringBuilder, so the output is

      123
      123

      When compiled with JDK 11 or later, the explicit invocation of incrementAndGet() using the "+" operator is executed before the implicit invocation of toString(), therefore the output is

      213
      123

            darcy Joe Darcy
            cwimmer Christian Wimmer (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: