- 关于对象不可变性的描述(百度的)
- String类的概述(API的翻译)
- 关于String不可变性的理解
- String创建的问题(我扯淡的,别信)
- 图示(我说的对的话,就是宋红康老师教的,尚硅谷牛逼)
- 总结
- 更新
第一次写博客,好tm激动。
关于对象不可变性的描述(百度的)
如果一个对象在创建之后就不能再改变它的状态,那么这个对象是不可变的(Immutable)。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型变量的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。(第一次写博客玩玩,你们也就随便看看啦,侵权了啥的求放过了。)
String类的概述(API的翻译)
String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
String str = "abc";
等效于:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
下面给出了一些如何使用字符串的更多示例:
System.out.println("abc");
String cde = "cde";
System.out.println("abc" + cde);
String c = "abc".substring(2,3);
String d = cde.substring(1, 2);
关于String不可变性的理解
首先String类由fina修饰,代表不可被继承。其次String在实现上也就是源码里采用的是
private final char[] value;(莫名其妙的咋是文本,将就下)
数组也是引用类型的变量,所以代表它的地址值是不变的。也就是说当你创建了一个String类型的对象,它就指向了内存空间中的地址,变是不可能变的,但是不变的是地址!
String创建的问题(我扯淡的,别信)
String比较特别,可以直接赋值。
String s = "cnm";
这就是在常量池创建了一个对象。
如果你是new出来的,如:
String s = new String("abc");
其实你是创建了两个对象,一个是常量池里面的,一个是堆空间里的,然后内容一样的话堆空间的是指向常量池的。
图示(我说的对的话,就是宋红康老师教的,尚硅谷牛逼)
图示:
总结
Sting类其实就是被封装成不可变的,你看,哪怕底层char[]地址不可变,你直接通过索引调用更改内容都是可行的。
public class StringTest {
public static void main(String[] args) {
final char[] chars = new char[]{'a','b','c'};
chars[0] = 'c';
System.out.println(chars);//cbc
}
}
综上所述
Java牛逼,sun公司牛逼,Oracle公司牛逼,尚硅谷牛逼。
是设计者把String封装成了不可变的。每次改变String的内容都会新增加一个变量。
至于为什么这样设计,好像是java设计者认为String类被创出来后一般都不会被改变,然后巴拉巴拉的决定每次改变都生成一个新的字符串运行效率高点。
更新
之前没看java9版本的api没注意,斯米马赛,java9里面把string底层改用了byte[]存储,因为用到String时通常都是a,b,c这样的字母,内存方面只需要一个字节就可以存储,当然中文什么的还是用的char[]存储,java内置有判断这样子的过程。