第十天(String)

   一个程序必须有输出,有输出必须有字符串。这一章将字符串,包括字符串内存机制,处理字符串几个类,当然也有笔者以前不甚了解的正则式了,故将正则式暂搁,容后再叙。

2011-05-25(字符串)
1、java中的字符串是用对象实现的,创建字符串的的时候,实际上时创建了String类的对象了。形式有两种:
                       String 引用变量名="字符串内容" 或者 String 引用变量名=new String(<字符串序列>)
若是字符串内容什么都没有,亦为一对象,只是引用变量所在指向的对象什么都没有,这与null有区别,null是指没有对象。
2、String类提供多种方法,在创建字符串对象后可直接使用。具体就不罗列了,只提下大概有什么样的方法:链接两字符串(concat())、字符取代(replace(char oldChar,char newChar))、获取子字符串(substring())、全部变为小写或大写(toLowerCase(),toUpperCase())、将前导和后继的非可见字符,如换行/n,去掉(trim())。还有一些获取长度、判断对象内容是否相等的方法就不提了。
3、字符串的内存机制。先给例子:
                                                             String s1="JavaSE6.0";
                                                             String s2="JavaSE6.0";
                                                             String s3=new String("JavaSE6.0");
打印s1==s2;s1==s3;s1.equals(s3),分别为true、false、true。"==",比较的是引用指向是否为同一对象,这是毫无疑问的,但结果为何会这样?说明结果之前,要看下String对象创建是,内存里发生了什么。首先要明白,java运行时,将内存分为推和栈,堆是储存创建的对象的(对象的堆积);栈储存的是方法调用过程中的局部变量或引用。而字符串实在太重要了,所以java在储存对象的堆中单独开辟一个空间来专门存放字符串对象。这个空间称为“字符串常量池”。
I、不使用new创建String对象。步骤是:
(1)查看字符串常量池中是否存在内容与"JavaSE6.0"相同的对象;
(2)若有,则直接使引用指向该对象;
(3)若无,则新创建一个,并使引用指向它。
根据上面这个,就能的得到合理的解释了。创建s1的时候:s1在栈里,指向的是字符串常量池中的"JavaSE6.0";而后创建s2:发现字符串常量池里已有"JavaSE6.0",所以s2就直接指向它。于是当判断s2、s2是否指向同一对象时,就返回了true。
II、使用new创建String对象。步骤是:
(1)创建之前不检查,直接在堆中创建对象,并用声明的引用指向它;
(2)创建之后,检查字符串常量池中是否有同内容的对象;
(3)若有,将new出来的对象(在堆中)与同内容的对象(在字符串常量池中)建立联系;
(4)若无,在常量池中建立一个,再联系。
所以,s1和s3指向的对象是不同的,故返回false(联系在一起不能算是指向相同)。String类提供了String intern()方法为在堆中的字符串对象用上面“联系”。intern()返回值是这样的:如果本身就在常量池中,放回自己的引用;如果在堆中,返回与其联系的对象的引用。所以,如果写成:s2==s3.intern()返回值就为true了。
4、String对象的永不变性与内存机制的代价。String类对象一旦创建了,就保留在字符串常量池中(或堆)中,不会改变,直到被清除。这一点与封装类一样,也可以改变引用指向起到“改变对象”的效果。这样的机制的效果有好有坏。好的是,常量池中字符串就与引用建立一一对应关系(就算是用new建立对象,但可以通过“联系”来使引用间接指向常量池中的对象),比较之时只需比较两个引用即可。坏的是,对象不能变,如果要进行修改操作(如链接两个字符串)就要再创建新的字符串对象,而把旧的对象遗留在内存中,内存压力很大。然而,鉴于实际上字符串的比较操作是多于修改操作的,java选择了这种机制。
5、StringBuffer类可弥补String类对象不可变的缺点,所以如果要对字符串进行多次的修改操作(实际上,String类提供很少的字符串修改的方法),用StringBuffer更有效率。StringBuffer类的方法就不提了,注意的是,StringBuffer中的equals()方法功能与“==”一样,是比较两个引用是否指向同一个对象,不同于String类中的比较引用指向的对象的内容是否一样。StringBuffer要比较内容要使用toString()方法后再比较。
6、StringBuilder类亦可弥补String类不能修改对象的不足。并且与StringBuffer类具有相同的功能。不同的是,StringBuiler效率稍微高一点,比之StringBuffer不足的是,多线程操作时,StringBuilder可能会产生问题。所以单线程一般用StringBuilder,多线程一般用StringBuffer。
7、就是正则式了,这里内容较多,另外再开文章。事实上,我也在努力看各位前辈的对于正则式的理解,等我有了自己的一套理解后,才能发。可能等下发,也可能明天,也可能更后,但一定发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值