String详解

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]  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值