关于String类的几个疑惑

春天画花卉校长 2016-05-25 04:34:53
今天看到String类的一个视频,其中说到这么一个问题:
如图,对于str1 = str1 + "Android"; 所指向的位置,我表示不懂。我在自己的Eclips中运行下列语句:

如果按照上面的说法,那结果应该是true,可是结果是false。
我觉得是不是str1 + "Android";会在堆中生成一个新的对象,其实并没有引用常量池中的常量。如果引用了,那么结果应该是true。
请各位大虾解惑。
...全文
668 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
------_------- 2016-06-11
  • 打赏
  • 举报
回复
一个人L 2016-06-10
  • 打赏
  • 举报
回复
字符串比较应该是equal
CoolTomato_ 2016-06-08
  • 打赏
  • 举报
回复
用equals方法就等了,string默认重写了equals方法,就比较内容是否一致,所以相等。而等号比较的则是地址,肯定不一致。我有关于String类的两篇博客不妨来看看,http://blog.csdn.net/qq_34944851
securitit 2016-06-08
  • 打赏
  • 举报
回复
引用 10 楼 zhaocp37 的回复:
用==是比较STRING对象的地址不是比较内容,如果要比较内容要用equals.
哥哥,你low了,你都没明白==和equals到底怎么回事就来回答了!!! 啥叫地址,啥叫值!!! 三楼说的对,因为str1是变量,所以编译时优化是不会处理的,所以就导致了重载的+操作,而String的重载+是通过StringBuilder实现的,所以str1最后的值已经不在常量池了。
快乐先生 2016-06-08
  • 打赏
  • 举报
回复
用==是比较STRING对象的地址不是比较内容,如果要比较内容要用equals.
gamedev˚ 2016-05-27
  • 打赏
  • 举报
回复
刚好学完这方面,我也来凑个热闹
引用 7 楼 u011150002 的回复:
看了大家的回复和网上找的一些资料现在明白一些了。 首先: 1: 对于 String str3 = "JavaEE" + "Android";这条语句会在编译时期确定,如果常量池中有 "JavaEEAndroid"则会将这个字符串的地址放到str3中。如果没有,则会在常量池中新建,然后赋值引用。 2: 对于 str1= str1 + "Android"; 在编译时并没有确定,只有在运行时才能确定值。所以会在堆中新建对象String 类型 然后赋值给str1; 这样str1 所引用的地址并不是"JavaEEAndroid"的地址。所以不相等。具体解释如2楼所示: [quote=引用 2 楼 m2200 的回复:] 你这个问题很有意思。 因为String相加本质上要先转换成StringBuffer再调用StringBuffer的append方法,最后调用toString方法,而你查看下toString方法就可以发现,他是这样实现的:new String(value, 0, count),而new出来的字符串是不存到常量池的。 就比如说你先String s1 = new String("abc"),再String s2 = "abc",比较s1和s2,他们也是不相等的,一个道理。
[/quote] 哥们,其实不止你一个人对这个问题感兴趣,而我就是其中的一个,我的帖子你看一下,我总结了一下 在22楼处 从最初不知道,到后来查阅资料以及提问。。。
  • 打赏
  • 举报
回复
看了大家的回复和网上找的一些资料现在明白一些了。 首先: 1: 对于 String str3 = "JavaEE" + "Android";这条语句会在编译时期确定,如果常量池中有 "JavaEEAndroid"则会将这个字符串的地址放到str3中。如果没有,则会在常量池中新建,然后赋值引用。 2: 对于 str1= str1 + "Android"; 在编译时并没有确定,只有在运行时才能确定值。所以会在堆中新建对象String 类型 然后赋值给str1; 这样str1 所引用的地址并不是"JavaEEAndroid"的地址。所以不相等。具体解释如2楼所示:
引用 2 楼 m2200 的回复:
你这个问题很有意思。 因为String相加本质上要先转换成StringBuffer再调用StringBuffer的append方法,最后调用toString方法,而你查看下toString方法就可以发现,他是这样实现的:new String(value, 0, count),而new出来的字符串是不存到常量池的。 就比如说你先String s1 = new String("abc"),再String s2 = "abc",比较s1和s2,他们也是不相等的,一个道理。
Blue_淩亂 2016-05-26
  • 打赏
  • 举报
回复
引用 2 楼 m2200 的回复:
你这个问题很有意思。 因为String相加本质上要先转换成StringBuffer再调用StringBuffer的append方法,最后调用toString方法,而你查看下toString方法就可以发现,他是这样实现的:new String(value, 0, count),而new出来的字符串是不存到常量池的。 就比如说你先String s1 = new String("abc"),再String s2 = "abc",比较s1和s2,他们也是不相等的,一个道理。
赞同!
  • 打赏
  • 举报
回复
public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=2, args_size=1 0: ldc #16 // String javaEE 2: astore_1 3: new #18 // class java/lang/StringBuilder 6: dup 7: aload_1 8: invokestatic #20 // Method java/lang/String.valueOf :(Ljava/lang/Object;)Ljava/lang/String; 11: invokespecial #26 // Method java/lang/StringBuilder. "<init>":(Ljava/lang/String;)V 14: ldc #29 // String hello 16: invokevirtual #31 // Method java/lang/StringBuilder. append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #35 // Method java/lang/StringBuilder. toString:()Ljava/lang/String; 22: astore_1 23: getstatic #39 // Field java/lang/System.out:Ljav a/io/PrintStream; 26: aload_1 27: invokevirtual #45 // Method java/io/PrintStream.prin tln:(Ljava/lang/String;)V 30: return
qq_34941962 2016-05-25
  • 打赏
  • 举报
回复
因为str1是个变量,编译时不能确定,它的值,可以给str1加上 final 就相等了
qq_16979125 2016-05-25
  • 打赏
  • 举报
回复
我本来的认知和你是一样的,然后看了上面几位的解释豁然开朗了,写了个测试类来试了试....
public class Test {
	public static void main(String[] args) {
		String s1 = "java";
		String s11 = "java";
		String s2 = "javaee";
		String s3 = s1+"ee";
		String s4 = "java"+"ee";
		System.out.println("s1==s11?"+(s1==s11));//true
		System.out.println("s2==s3?"+(s2==s3));//false
		System.out.println("s2==s4?"+(s2==s4));//true
		System.out.println("s3==s4?"+(s3==s4));//false
		System.out.println("s2==javaee?"+(s2=="javaee"));//true
		System.out.println("s3==javaee?"+(s3=="javaee"));//false
		System.out.println("javaee==java+ee?"+("javaee"=="java"+"ee"));//true
		System.out.println("java==java?"+("java"=="java"));//true
	}
}
咋个办呢 2016-05-25
  • 打赏
  • 举报
回复
按着java api的说法,对象相等不一定对象的hashcode相等,这要看具体的hashcode实现。 另外,string在内存中相同的string对象会粗放在同一个内存空间,但是hashcode并不是内存的引用地址,而是java用来检索对象的hash值。 看一下string类的hashcode()方法的源代码就知道了: public int hashCode() { int h = hash;//如果是直接""方式定义的string对象,则hash默认为0; if (h == 0 && value.length > 0) { char val[] = value;//string对象在java中是char数组存在。 for (int i = 0; i < value.length; i++) { h = 31 * h + val[i];//通过这句话你就知道如果string对象相同,那么计算出来的hashcode值是一样的。 } hash = h; } return h; }
爱睡觉的阿狸 2016-05-25
  • 打赏
  • 举报
回复
你这个问题很有意思。 因为String相加本质上要先转换成StringBuffer再调用StringBuffer的append方法,最后调用toString方法,而你查看下toString方法就可以发现,他是这样实现的:new String(value, 0, count),而new出来的字符串是不存到常量池的。 就比如说你先String s1 = new String("abc"),再String s2 = "abc",比较s1和s2,他们也是不相等的,一个道理。
拘谨的小人 2016-05-25
  • 打赏
  • 举报
回复
== equals

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧