Please consider the following class:
class Eq { public static void main(String[] args) { System.out.println("" == ".".substring(1)); } }
The example is supposed to show that multiple copies of the empty string may exist in memory. I still have an old OpenJDK 11 where the program outputs false
as expected. Under OpenJDK 15, the program outputs true
. The generated bytecode for the class files looks similar (even though they differ in register values):
Java 11:
public static void main(java.lang.String[]); Code: 0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #13 // String 5: ldc #15 // String . 7: iconst_1 8: invokevirtual #17 // Method java/lang/String.substring:(I)Ljava/lang/String; 11: if_acmpne 18 14: iconst_1 15: goto 19 18: iconst_0 19: invokevirtual #23 // Method java/io/PrintStream.println:(Z)V 22: return
Java 15:
public static void main(java.lang.String[]); Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String 5: ldc #4 // String . 7: iconst_1 8: invokevirtual #5 // Method java/lang/String.substring:(I)Ljava/lang/String; 11: if_acmpne 18 14: iconst_1 15: goto 19 18: iconst_0 19: invokevirtual #6 // Method java/io/PrintStream.println:(Z)V 22: return
I tried to exclude static compiler optimizations by reading "." from stdin but this does not change the outcome. I have tried to disable the JIT via -Djava.compiler=NONE
and played around with adjusting the string table size via -XX:StringTableSize=100000
. I now have the following questions:
I think just strategies to approach how to find the reason for the behaviour that don't answer the question might also be interesting.
It is an open-source reference implementation of Java SE platform version 11. Java 11 was released after four years of releasing Java 8. Java 11 comes with new features to provide more functionality. Below are the features which are added in the four and a half years in between these two versions.
There are three ways to compare String in Java: By Using equals() Method. By Using == Operator. By compareTo() Method.
To compare these strings in Java, we need to use the equals() method of the string. You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not.
This is mentioned in the JDK 15 Release Notes.
It was changed as requested by JDK-8240094:
JDK-8240094 : Optimize empty substring handling
String.substring
return""
in some cases, but could be improved to do so in all cases when the substring length is zero.
Related:
JDK-8240225 : Optimize empty substring handling
Optimize
String.substring
and related operations likestripLeading
,stripTrailing
to avoid redundantly creating a new empty String.
Sub Task:
JDK-8251556 : Release Note: Optimized Empty Substring Handling
The implementation of
String.substring
and related methodsstripLeading
andstripTrailing
have changed in this release to avoid redundantly creating a new empty String. This may impact code that depends on unspecified behaviour and the identity of empty sub-strings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With