常量池中的字符串
String类的特点
- String类是final类,它的成员方法都默认为final方法,成员变量是final的char数组
- String对象一旦被创建就是固定不变的了,对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象。
- 把数组所有值转换为字符串,可以节省内存
- String s = new String(); 等效于 String s = “”; 不等效于 String s = null;
常见问题
String和Array的转化
char[] a={ 'a ', 'b ', 'c '};
String b=new String(a); //字符数组到字符串
char[] c=b.toCharArray(); //字符串转换成字符数组
==和equals()比较
字符串存储
为什么String类是不可变类
// String类源码
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
从上面String类源码中,可以看出,String类通过final数组来存储字符串,而这只能保证数组引用地址不可变
,数组内容是可变的
。
String不可变,关键是因为SUN公司的工程师,在后面所有String的方法
里很小心的没有去动Array里的元素
,没有暴露内部成员字段。private final char value[]这一句里,private
的私有访问权限的作用
都比final大
。而且设计师还很小心地把整个String设成final禁止继承
,避免被其他人继承后破坏
。也就是说,String是不可变的关键都在底层的实现,而不是一个final
。考验的是工程师构造数据类型,封装数据的功力。
private
保证其他人不能
对普通类型成员的值和对象成员的成员变量进行改动
(如String的char[]内的元素),final
保证普通类型成员变量的值和对象成员变量的指针对任何人都不可改
(当然不写final,小心一点也可以保证不改,但是,写上final起到了保证作用
)
注意事项
- 字符串常量也是对象的一种,可能存在于常量池中,也可能存在于堆上。如
String s1 = "abc"; //在常量池中的对象
String s2 = new String("abc"); //在堆中的对象
参考文献
http://www.hollischuang.com/archives/99 String详解
https://www.cnblogs.com/xiaoxi/p/6036701.html String和常量池存储
https://www.zhihu.com/question/31345592/answer/114126087 为什么String类是不可变类