最近复习一些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";