public static void main(String[] args) { String s1 = "hello"; String s2 = "world"; String s3 = s1+s2; String s4 = "hello"+"world"; System.out.println(s4=="helloworld");
System.out.println(s3=="helloworld");
System.out.println(s3==s4);
}
运行的结果是:true
false
false
关于第一个,我知道是因为字符串相加编译器自动的转成String s4 = "helloworld";这样在比较s4=="helloworld",
所以结果就为true,因为他们都指向了字符串池中的唯一一个"helloworld"。
第二个就不明白了。
这样要看字符串对比时,是对比内存位置,还是对比字符串的值完全相等.
如果对比字符串的值完全相等,那这个地方应该所有的值都为true,所以假设他是对比内存位置.
1.S4明显将是一个常量.2个字符串内容相等,自然会在字符串常量池中有同一个位置.
2.s3将会是一个变量.这时.虽然S3的值等于helloworld,但位置却是不同的.
3.一个道理.s4既然等于常量helloworld自然就不会等于变量helloworld
噢,对了,s3是一个变量了,那我想问一下,是不是这个变量存储的地址就不可能指向的是字符串常量中的helloworld,而是重新new了一个字符串,所以s3=s1+s2这句话相当于这样了s3=new String(s1+s2);
@mr生如夏花: s1 s2也是变量.只是他们指向一个静态字符串.
2个变量相加自然等于1个新变量.而2个静态字符串相加,如果你查看生成后的运行时代码会发现编译器直接把2个静态字符串合并成一个了.这个是编译器优化的结果
@吴瑞祥: 明白明白,感谢
项目中多用equal比较
嗯,是是,我还知道一般不用str.equal("")的形式,而是用"".equal(str)的形式,可是真想探究一下这个问题。
@mr生如夏花: 你的理解已经到位了。常量只是编译器优化的结果。
@angelshelter: 噢噢,好的,谢谢哈。在做面试准备,所以想的有点多了
==的比较引用,equal是比较值。明白这个就ok了。
嗯嗯,谢谢
楼主,这个说白了就是值类型和引用类型了。如果面试有这个的话,你就把值类型和引用类型的区别一说就ok
这里边有个创建字符串的问题,问题还是比较多
@mr生如夏花: 创建的字符串是一个新的变量,是一个新的对象。这样应该还是属于值类型和引用类型吧?这个可以一起交流下,我的表达能力也不太好。