前言
说起来字符串,那就要从当年刚开始学c++开始说起了,当年咱由于太笨,用不了char数组表示字符串,就来csdn搜寻有无代替char数组的东西,然后就发现了字符串这个神奇的东西,今天咱们来聊一聊java中的字符串的操作。
小知识
先看一下这个经典题目
String s1 = "a";
String s2 = "b";
String s3 = "ab";
String s4 = "a" + "b";
String s5 = s1 + s2;
String intern = s4.intern();
System.out.println(s3 == s4);
System.out.println(s3 == s5);
System.out.println(s3==intern);
System.out.println(s5==intern);
兄弟们有兴趣的评论一下答案,俺们一起交流交流,
想好答案了吗,想好答案了就往下看哈,公布答案了哈
和大佬评论的一样吗,接下来我们一个个解析一下
s3==s4?
这里要提到一个java内存结构中的一个结构,叫做串池(StringTable),他的主要作用就是存储字符串常量这类的对象,如下的代码
String s="123"
String s2="123"
这里的s对象就是存储在串池中,对于s2对象,因为s2存储的字符串与s相同,因此不需要再串池中存储新的对象,因此s与s2实际指向的是一个对象。
能够理解上述内容的,我们再提出另一个特性,在java编译时,会把"a"+"b"与"ab"作为相同的常量处理,因此在处理一下两块代码,
String s="ab"
String s2="a"+"b"
与
String s="ab"
String s2="ab"
处理是相同的,即s与s2指向的对象相同,因此s3==s4
s3==s5?
这里我们要好好说说下面这串代码了,我是没有想到这么简单一小串代码,居然也这么神奇,来和博主一起看看把。
String a="a";
String b="b";
String c=a+b;
首先咱们先反编译一下看一下,
偶,看看这让人头大的代码,但还好后面给了我们注释。
0-5的操作都很正常,就是在常量池拿去#2与#3对应的字符串常量,也就对应了前两行代码。
但6就有些奇怪了,居然出现了new,这说明新创建了对象,可以通过常量表去查询,也可以看后面的注释,可以看出创建了一个StringBuilder对象,中间命令直接跳过,我们看下21这里,发现调用了toString方法,我们来看一下这个方法,
我们发现这个方法原来是返回一个新创建的对象,这下就清晰了,原来a+b拼接时会调用StringBuilder产生一个新的对象来赋值给c,因为new出来的对象是在堆中新创建一个对象。
来回到上面的内容
String s3 = "ab";
String s5 = s1 + s2;
s3指向的是串池中的对应的"ab"字符串对象,而s5则是指向堆中新生成的另一个对象,因此s3!=s5
intern==s3?
这个就比较简单的,我们只需要知道字符串的intern()是将调用该方法的字符串存入串池中即可,因为串池是一个hash表的结构,因此再存入时,首先判断串池中有无相同的内容的字符串对象,若是没有则存入,若有则不进行操作,两种情况最终都会返回串池中对应的字符串对象,因此intern指向的实际上就是串池中"ab"对应的字符串对象,故s3=intern,同理,由上一部分我们可以知道s5是新生成的对象,因此intern!=s5
总结
近一段时间一直在补java知识,这篇博客可以说自己在学习网课之后做的一个笔记,如果内容有错误,欢迎大佬们指正,感谢大家的阅读。