关于 Java String

 

Java 关于String 有这样一段描述“字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。

这段描述中有几个关键词:

1.常量:也就是说一个字符串创建后就不能被修改,所有的添加,删除操作都会生成新的对象。既:

String s="abc";//创建s引用和值为"abc"的对象,s指向该对象

s+="d";//创建值为"abcd"的对象,此时s指向新的对象

2.字符串缓冲池:

缓冲池为String类私有维护,既如果你字面(隐式)声明一个String对象,该对象并不是存在应用程序堆中,而是在字符串缓冲池中,对象引用是指向String Pool中的对象。同样刚才的例子:

String s="abc";//s指向的是String Pool中的对象

而如果显示声明对象,则会有不同的结果,它会先查询String pool 中是否存在值为"abc"的对象,如果不存在,则会在String Pool中创建,然后再在堆中新建一个值为"abc"的对象,引用S指向堆中的对象:

String s=new String("abc");//s指向Heap 中的对象

3.共享

因为String对象不可变,既可以共享。

当再声明一个s1对象,值为"abc",这是Java查询缓冲池,发现已经存在了值为"abc" 的对象,此时该语句不生成对象,返回String pool中值为"abc" 的引用。

String s="abc";//s指向的是String Pool中的对象

String s1="abc";//该语句不生成对象,只是返回String pool中对象的引用

4.假如我已声明一个String对象,这是我想再添加内容,我用‘+’操作符连接两个字符串。

例如:

String s1="abc";

String s2=s1+"def";//使用+连接两个字符串

此时Java又是怎么做的呢?

查看API文档,有这样一段描述:

Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。

也就是说使用+操作符时,会生成一个StringBuilder中间对象,然后通过toString()方法返回结果。通过单步调试,我们发现Java采用反射机制构建StringBuilder对象。这样知道我们经常使用的字符串连接操作符+添加字符串内容是一件相当”昂贵“的操作。建议直接使用StringBuilder。

那么上述中s2指向何处呢?答案是堆中的对象,StringBuilder生成在堆上,返回的既是堆上的String

5.那么直接使用字符串连接会不会产生新的对象呢?

我们来看一个测试:

String s2="abcdef";

String s3="abc"+"def";

System.out.println(s2==s3);

结果是什么呢?True

对于两个(字面)字符串的连接,Java会直接将两个字符串连接成一个字符串,然后与String pool中的对象比较。

6.intern()方法

关于String 类还有一些有趣的东西。

Java 对于intern()的方法描述是:

返回字符串对象的规范化表示形式。

一个初始为空的字符串池,它由类 String 私有地维护。 

当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。 

它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

什么意思呢?就是如果该对象是堆上的对象,则返回池中相对应的对象。如果池中没有对应的对象,则添加一个String对象进去,并返回此对象的引用。

这是我们的测试结果:

String s1="abc";

String s2="ab";

String s3=s2+"c";

System.out.println(s1==s3);//false

System.out.println(s1==s3.intern());//true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值