回答标题问题:技术上仅限运行时,因为在编译期间没有String可以实习的池。
但是,源文件中定义的所有字符串字面量和常量值字符串在程序启动时会自动被实习,并且可以使用该String#intern()方法来实习其他字符串。
此外,对于未来的读者:OP 的结果似乎是一个 IDE 怪癖,在所有事情中。public static void main(String string_input)OP 最初是通过 BlueJ 的自定义主方法签名将输入作为命令行参数输入。显然,BlueJ 在幕后做了一些恶作剧,以使这种匹配public static void main(String[] args)JLS 所需的签名,显然这些恶作剧涉及在某些时候对输入字符串进行实习,从而导致 OP 的结果。
编辑以下答案:看起来我犯了一个小的阅读错误。虽然这个答案以某种方式(有点)有效,但它依赖于这样一个事实,string == string_input在 OP 更新问题之前我无法确认(这显然无法完成,因为源代码已被删除)。
答案可以在源代码中找到String:
public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}
注意最后一行: if beginIndex == 0,原件String本身被返回。因此,在案例 1 中,string确实指向与 相同的对象string_5,因此true被打印。
但是,如果beginIndex != 0,则创建一个 new String,因此string不再指向与 相同的对象string_5,因此false打印。