源码
java
1 |
|
String的特性
- 1、String类是final的,不可被继承。
- 2、String类是的本质是字符数组char[], 并且其值不可改变。
- 3、String类对象有个特殊的创建的方式,就是直接指定比如String x = “abc”,”abc”就表示一个字符串对象。而x是”abc”对象的地址,也叫做”abc”对象的引用。
- 4、String对象可以通过“+”串联。串联后会生成新的字符串。
- 5、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。
String对象的创建
原理
- 原理1:当使用任何方式来创建一个字符串对象s=X时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
- 原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
- 原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
- 原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
方式
- 其一,使用new关键字创建字符串,比如String s1 = new String(“abc”);
- 其二,直接指定。比如String s2 = “abc”;
- 其三,使用串联生成新的字符串。比如String s3 = “ab” + “c”;
String s=”abc” 和String s= new String(“abc”)的区别
从源码中可以看出,String 是一个final 类型的 char数组。
不论是String s=”abc” 还是String s= new String(“abc”),在编译期生成的.class文件中,“abc”都已经被存储在 CONSTANT_String_info表(在class文件常量池中)中,当.class文件被JVM加载时,JVM会创建一块 String Pool(在运行时常量池中)。
当执行String s=”abc” 时,JVM首先在String Pool中查看是否存在字符串对象“abc”(如何查看呢?用equals()方法判断),如果已存在该对象,则不用创建新的字符串对象“abc”,而直接使用String Pool中已存在的对象“abc”,然后将引用s指向该对象;如果不存在该对象,则先在String Pool中创建一个新的字符串对象“abc”,然后将引用s指向String Pool中创建的新对象。
而String s= new String(“abc”)则会在堆中创建一个String对象,并且为这个String对象的char数组赋值为常量池中的“abc”。所以,这句代码其实创建了两个对象,一个是在编译期间创建的,一个是在new的时候创建的。