关于String类型变量问题,结果让我很疑惑,求解答。

军区文工团 发布于 2012/03/17 22:37
阅读 254
收藏 0
public static void main(String[] args) {
compare("2", "2");
}
public static void compare(String a1,String b1)
{
String a="1"+a1;       //a="12"
String b="1"+b1;     //a="12"
String c="1"+"2";     //a="12"
String d="1"+"2";     //a="12"
System.out.println(a==b) // 为什么这里返回false
System.out.println(c==d);// 这返回的却是true
} 

以下是问题补充:

@军区文工团:刚没注意,应该 abcd都是"12" (2012/03/17 22:38)
加载中
0
UlricQin
UlricQin

System.out.println(a==b) // 为什么这里返回false

这个返回false是因为a和b是两个对象,地址肯定不同

System.out.println(c==d);// 这返回的却是true

这个是true是因为:

String c="1"+"2";     //a="12"
String d="1"+"2";     //a="12"
"1"+"2";在编译期就可以确定结果"12",两个相同的字符串常量,地址相同,所以是true

0
中山野鬼
中山野鬼
你确定S是大写?
0
aiasfina
aiasfina

楼上正解。javap一下一目了然。

      40: ldc           #9                  // String 12
      42: astore        4
      44: ldc           #9                  // String 12
      46: astore        5

 

0
崔钢
崔钢

要知道,java中的String是final的。其内部有缓冲。从这个角度理解会比较好理解。在java中,凡是字面值相同的String其引用都是相等的。如果没有合并,那么abcd应该都是相等的。但是由于有合并运算,这个就不同了。由于java是不可变的,所以合并运算必然会产生新的对象,因此a和b就不等了。理论上c和d也不等,但是由于c和d是字面值运算,因此现代JVM会对这种运用进行优化,c和d其实并没有运算,他们的值一开始就等于“12”因此他们会指向同一个对象,基于我说的第一条。

六只
六只
如果你说的合并是intern,那么你应该说错了。:)
军区文工团
军区文工团
谢谢,现在明白了。
0
中山野鬼
中山野鬼

引用来自“titanrain”的答案

System.out.println(a==b) // 为什么这里返回false

这个返回false是因为a和b是两个对象,地址肯定不同

System.out.println(c==d);// 这返回的却是true

这个是true是因为:

String c="1"+"2";     //a="12"
String d="1"+"2";     //a="12"
"1"+"2";在编译期就可以确定结果"12",两个相同的字符串常量,地址相同,所以是true

这个我不是太认同。当然不能说你讲错了,毕竟我搞不清楚楼主是哪个语言。如果是C++标准的string,注意 s是小写的。 == 操作,和> < >= <= !=一样,是对两个容器内的数据,按照字典法进行比较输出结果的。因此实际还是对内容的操作。

看了你的帖子,我也又验证了一下,至少string(s小写)cout << (a  == b);是为1的。

中山野鬼
中山野鬼
所以我得确认一下。呵呵。
deleted
deleted
哥们儿,这是java,不是c++......
0
aiasfina
aiasfina

引用来自“崔钢”的答案

要知道,java中的String是final的。其内部有缓冲。从这个角度理解会比较好理解。在java中,凡是字面值相同的String其引用都是相等的。如果没有合并,那么abcd应该都是相等的。但是由于有合并运算,这个就不同了。由于java是不可变的,所以合并运算必然会产生新的对象,因此a和b就不等了。理论上c和d也不等,但是由于c和d是字面值运算,因此现代JVM会对这种运用进行优化,c和d其实并没有运算,他们的值一开始就等于“12”因此他们会指向同一个对象,基于我说的第一条。

我记得好象是String字面量会自动"intern",JVM返回常量池中已经存在的字符串的引用。
0
Raynor1
Raynor1
STRING也有自己的compareto的实现的吧。。看一下就懂了。
0
六只
六只
jvm会在编译期进行规格化,规格化之后就是放到字符串常量池中了。所以c、d相等,因为他们都是指向常量池中的那个地址。
0
肥添
肥添

引用来自“六只”的答案

jvm会在编译期进行规格化,规格化之后就是放到字符串常量池中了。所以c、d相等,因为他们都是指向常量池中的那个地址。
同意楼上说法,是常量池的原因,当 a='1' 的时候,跟a=new String('1') 是有差别的,前者会去常量池取,没有则添加到常量池中,后者是开辟新空间~~
返回顶部
顶部