Java 游泳池什么时候换?
我有两个问题:Java 游泳池什么时候换?,java,string,pool,Java,String,Pool,我有两个问题: public static void main(String[] args) { String s1 = "bla"; String s2 = "b" +"l" + "a"; String s3 = "b".concat("l").concat("a"); if(s1 == s2) System.out.println("Equal"); else System.out.println("Not equal"); if(
public static void main(String[] args) {
String s1 = "bla";
String s2 = "b" +"l" + "a";
String s3 = "b".concat("l").concat("a");
if(s1 == s2)
System.out.println("Equal");
else
System.out.println("Not equal");
if(s1 == s3)
System.out.println("Equal");
else
System.out.println("Not equal");
}
- 为什么
和s1
指向同一个对象,而s2
和s1
不指向同一个对象?(不使用s3
关键字)new
- 如果我从用户处获得一个字符串,并将这些行添加到上述代码中:
如果用户输入BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); String name=in.readLine(); if(name.equals("test")) s1 = s1 + "xyz";
,程序将打印xyz
,当用户输入其他内容时,程序将输出notequal
。这是否意味着池在整个程序的执行过程中发生变化?优化器是否在编译时工作,并在运行时继续工作equal
String
是不可变的
,因此String类的任何方法都将返回一个新的String对象(不过也有一些例外-一个是substring
方法)。因此,concat
方法创建一个新字符串,该字符串进入堆,并且不会添加到常量池
就s1
和s2
而言,这两个字符串在编译时都是已知的,因此它们是相同的字符串文本
请注意,第二个字符串中的串联操作:-
String s2 = "b" +"l" + "a";
在编译时求值,结果已知与第一个字符串相同,并向常量池创建一个条目
为什么s1和s2指向同一个对象,而s1和s3不指向?(不使用new关键字)
因为连接发生在编译时,因此完成的字符串与第一个示例中的一样进入常量池。这是编译器“已知”的特例。这实际上意味着,通过这种方式连接多行的长字符串仍然可以获得与简单字符串常量相同的性能改进
在第二个示例中,您在运行时执行计算,因此它不会成为常量池的一部分
但是请注意,在JLS中,字符串常量池中可以和不能包含的内容的详细信息故意不明确,因此不同的实现可能会以不同的方式进行优化。它指定了某些规则,以确定其中必须包含的内容,但不依赖于这种行为在各个实现之间的一致性。有时(当编译器在运行时很明显字符串的值是什么时),编译器使用字符串池,而在其他情况下则不使用
实际上,您的代码不应该依赖于使用或不使用池的事实。
您不能总是运行main,因此如果您想查看是否从池中使用了字符串,可以使用javap对代码进行反编译。清单相对来说是不言自明的