String存放在内存中的哪块区域?
JDK7开始分配在堆中。
在JDK6的时候在Java虚拟机(这里指的是HotSpot)中内存区域分为本地方法栈、虚拟机栈、堆、程序计数器、方法区等,方法区又被称作永久代。 在Java虚拟机内存中有个区域叫做运行时常量池,是方法区的一部分。在JDK6中其中存放的有类的版本、字段、方法、接口等描述信息以及常量池,常量池用来存放编译期间生成的各种字面量和符号引用,字符串就存储在这个位置。
在JDK7中字符串已经从常量池中移除,方法区有被取消掉的趋势,字符串的存储位置已经被移到了堆中。
永久代已经在JDK8中移除。 在JDK8中新出现的内存区域叫做元空间,其位于本地内存中。字符串的存储位置在堆中。
理解String不可变
每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象。
String q = "hello";
println(q);
String qq = upcase(q);
println(q);
println(qq);
//上述代码的输出结果
hello
hello
HELLO
String a = "a"和String a = new String("a")有什么不同?
第一个显然只有一个对象,第二个却有两个对象"a"和new String("a")。
String ab = "cd";String ac = "cd";
这里还是一个对象!
为什么?因为jvm中存在一个String池,存放着String对象,用于共享使用,提高效率。当执行ab的语句时,会调用equal去跟String池中比较看存不存在“cd”这个值得对象,如果存在,则返回这个对象给ab,如果不存在,则把这个值得对象加入String池。当执行完ab,再执行ac时,由于String池已经存在值为"cd"的ab对象,因此会把该对象的引用赋给ac。这么看,String池的存在很合理。但是String池只能添加使用引号包含文本的方式产生的对象,而不能添加使用new操作产生的对象。
String,StringBuffer和StringBuilder的区分和使用场景?
一般来说,三者的速度是:StringBuilder > StringBuffer > String。
但是,在String a = "how" + "old" + "are" + "you"。这种直接拼接的情况下,String速度最高。这是因为jvm的优化问题,jvm会自动识别,把"how" + "old" + "are" + "you"直接当做'how old are you"。
StringBuilder是jdk1.5引入的,1.5之前只能使用StringBuffer。
StringBuffer是线程安全的,StringBuilder是非线程安全的。
String的使用场景:在字符串不常变化的情况下,例如进行字符串的复制和简单得拼接
StringBuffer的使用场景:在字符串经常进行运算的,且在多线程的情况下,例如xml解析和StringBuffer参数的拼接
StringBuilder的使用场景:在字符串经常进行运算的,且在单线程的情况下,例如SQL语句的拼装。
利用String的split()对字符串进行切割
String text = "Hello, my name is liujianfeng";
System.out.println(Arrays.toString(text.split("\\s")));//以空格为切割符
System.out.println(Arrays.toString(text.split("\\W+")));//以非单词为切割符
System.out.println(Arrays.toString(text.split("m")));//以字母m为切割符
String number = "Hello, 985 or 211, I will say ssooss";
System.out.println(Arrays.toString(number.split("\\d")));//以数字为切割符
System.out.println(Arrays.toString(number.split("\\D")));//以非数字为切割符
System.out.println(Arrays.toString(number.split("[Ho]")));//以非数字为切割符
System.out.println(Arrays.toString(number.split("1{2}")));//以两个1为切割符
结果如下:
[Hello,, my, name, is, liujianfeng]
[Hello, my, name, is, liujianfeng]
[Hello, , y na, e is liujianfeng]
[Hello, , , , or , , , , I will say ssooss]
[, , , , , , , 985, , , , 211]
[, ell, , 985 , r 211, I will say ss, , ss]
[Hello, 985 or 2, , I will say ssooss]