请考虑以下类别:
class Eq {
public static void main(String[] args) {
System.out.println("" == ".".substring(1));
}
}
该示例应该显示内存中可能存在空字符串的多个副本。我仍然有一个旧的openjdk 11,在那里程序输出 false
一如预期。在openjdk15下,程序输出 true
. 为类文件生成的字节码看起来相似(尽管它们的寄存器值不同):
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
我试图通过从stdin中读取“.”来排除静态编译器优化,但这不会改变结果。我试图通过 -Djava.compiler=NONE
通过调整字符串表的大小 -XX:StringTableSize=100000
. 我现在有以下问题:
有人能重现这个问题吗(例如,我做得对吗?如果有帮助,我可以提供类文件)
我如何找出不同行为的确切原因?
你认为不同行为的根源是什么?
我认为,如何找到不回答问题的行为的原因的策略可能也很有趣。
1条答案
按热度按时间tuwxkamq1#
JDK15发行说明中提到了这一点。
按照jdk-8240094的要求进行了更改:
jdk-8240094:优化空子串处理
String.substring
返回""
在某些情况下,但在子串长度为零的所有情况下都可以进行改进。相关:
jdk-8240225:优化空子串处理
优化
String.substring
以及相关操作,如stripLeading
,stripTrailing
以避免冗余地创建新的空字符串。子任务:
jdk-8251556:发行说明:优化的空子字符串处理
实施
String.substring
以及相关方法stripLeading
以及stripTrailing
在此版本中进行了更改,以避免冗余地创建新的空字符串。这可能会影响依赖于未指定行为和空子字符串标识的代码。