最近复习一些java的知识点,看到String这一块,有不一样的感受,话不多说,来一起看看吧
String的相等情况
C/C++中没有String这个类,java才有。
首先讨论一下String的存放问题
String str1="abc"; str1="def";
str1申请放在栈内存中,内存中放的是abc字符串,当执行第二条语句是,这时str1指向的内存已经改变了,是另一块放def字符串的内存,但是abc字符串的内存依旧存在,只不过程序结束后,java虚拟机直接回收了。
String str2="abc"; System.out.println(str1==str2);
输出答案是true
这是为什么呢?
因为String常量池,在栈内已经有"abc"的内存了,再赋值就去栈内存中找,所以str1和str2指的是同一块内存区域。
既然这么说了,那么让我们来看下面这行代码,猜猜输出的true还是false
String str3=new String("abc"); System.out.println(str3==str1);
答案是false。
没想到吧!new出来的对象放在堆里,str3和str1内容虽然相同但是存在的内存区域不一样,所以它俩不一样。
这时候,如果你只是想判断它俩内容是否相就需要用到String的equals方法。
System.out.println(str3.equals(str1));
这时候输出的就是true了。
字符的增加情况
先来说说,String字符串要是想增加,非常方便,只需要"+"来拼接字符串。
String str1="abc"; String str2="def"; str1=str1+str2; System.out.println(str1);
输出的abcdef
但是我觉得有必要阐述一些这几行代码执行的原理
首先在栈内把abc、def字符串放进去,然后str1和str2分别指向它们,但是到了第三行代码,是将'abc'和'def'拼接在一起之后在放入到栈内中,此时这个新的字符串占得是另一块内存空间了,而不是str1最开始占用的那块。
总的来说,就是String类型的字符串拼接不是在原来的内存区,而是新的内存区。
如果有大量的字符串拼接情况,可想而知,String要把jvm虚拟机累死。
所以java又提供了另外两种字符StringBuilder和StringBuffer,两者都是通过append来增加字符,而且都是在原内存区进行字符串拼接。
Stringbuilder a=new StringBuilder("abc"); StringBuffer b=new StringBuffer("def"); a.append("def"); b.append("abc");
这两者都是速度比String快很多,其中StringBuilder的性能更好,缺点就是线程不安全。最好使用StringBuffer.
注意:两个不能直接赋值
StringBuilder a="abc"; StringBuffer b="def";