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

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

    XMLWordPrintable

Details

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

    Description

      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

      Attachments

        Issue Links

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved: