String字符串不是八大基本数据类型
而是 public final class 类里的
遇见这样一个题目
String str = "123";
int x=4,y=5;
str += (x+y);
System.out.println(str);
---------------------
问输出结果是:
A.12345 B.123+4+5 C.1239 D.编译时发生异常
可以测试一下.答案是 C. 1239
也就是说String可以被改变了??? ???
难道给的定义错了吗?
很明显不是的.
揭密:
测试代码:
public static void main(String[] args) {
String str = "a";
int x = 4;
int y = 5;
System.out.println("str =" + "a的哈希码 " + str.hashCode());
str = str + (x+y);
System.out.println("str =" + "ab的哈希码 " + str.hashCode());
}
运行结果
可见他们不是同一个地址的值
这个问题要从字符串的存储说起,比如普通字符串(String str = “Hello”),其中“Hello”存储在内存的一块区域中,而str可以看做一个指向那块内存的引用,当我们对字符串“Hello”进行修改的时候,并不是针对那一块内存进行修改,而是另外开辟一块新内存,把计算的结果存储到新开辟的内存空间中,所以说String类型的字符串是无法修改的。
StringBuilder和StringBuffer也是指向内存中一个字符串的,但是针对StringBuilder和StringBuffer类型的字符串进行操作的时候,修改是针对这一块内存的,或在这一块内存高位与低位增加新字符,或将内存中的字符删除,内中算法用c的思维想~
关于字符串,涉及到大量加减操作的最好用StringBuffer和StringBuilder,另外要分清:StringBuffer是线程安全的,而StringBuilder是非线程安全的,也就是说涉及到多个线程对同一个字符串操作的时候,用StringBuffer。
另外关于字符串还有性能的考虑,这里就不深究了~~
这个是一个博客里面大佬的介绍,有点迷茫吗?那看这个
你有一个电视遥控器str,它控制电视机a。
str+="b"后,产生了一台新的电视机叫ab,现在遥控器str控制ab。
但是电视a还是存在的,只是你手上没有遥控器控制它而已。
也就是说你已经取不到字符a了,但是它其实仍然在内存中。它不可改变。
如果用StringBuffer.则经过以上操作后,电视机a就不存在了,只有新产生的电视机ab存在。……
这样还迷茫吗?不了吧
在看看我的理解:
三个String的区别:
String | 区别 |
---|---|
String | 不可以被改变,因为被 final 修饰 |
StringBuilder | 是在原来的地址上进行的值得改变 , 但是非线程安全 |
StringBuffer | 是在原来的地址上进行的值得改变 , 是线程安全的,被synchronized(同步锁)修饰 |
对于需要多次修改的字符串的操作做好不要用String而选用其他两个,因为每次生成新的String的时候会产生内存空间的浪费
在不需要那么高的同步和安全性的时候常常使用 StringBuilder
在需要高的同步和安全性的时候使用 StringBuffer