按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
个自变量开头
endsWith() 可能是这个 String 后缀的一个 String 一个布尔结果,指出自变量是不是一个后缀
indexOf();lastIndexOf() 已覆盖:char,char 和起始索引,String,String 和起始索引 若自变量未在这
个String 里找到,则返回…1;否则返回自变量开始处的位置索引。lastIndexOf()可从终点开始回溯搜索
substring() 已覆盖:起始索引,起始索引和结束索引 返回一个新的String 对象,其中包含了指定的字符
子集
concat() 想连结的String 返回一个新 String 对象,其中包含了原始 String 的字符,并在后面加上由自变
量提供的字符
relpace() 要查找的老字符,要用它替换的新字符 返回一个新 String 对象,其中已完成了替换工作。若没
有找到相符的搜索项,就沿用老字串
toLowerCase();toUpperCase() 无 返回一个新 String 对象,其中所有字符的大小写形式都进行了统一。若
不必修改,则沿用老字串
trim() 无 返回一个新的String 对象,头尾空白均已删除。若毋需改动,则沿用老字串
valueOf() 已覆盖:object,char'',char''和偏移以及计数,boolean,char,int,long,float,double
返回一个String,其中包含自变量的一个字符表现形式
Intern() 无 为每个独一无二的字符顺序都产生一个(而且只有一个)String 句柄
可以看到,一旦有必要改变原来的内容,每个 String 方法都小心地返回了一个新的 String 对象。另外要注
意的一个问题是,若内容不需要改变,则方法只返回指向原来那个String 的一个句柄。这样做可以节省存储
空间和系统开销。
下面列出有关StringBuffer (字串缓冲)类的方法:
方法 自变量,覆盖 用途
构建器 已覆盖:默认,要创建的缓冲区长度,要根据它创建的String 新建一个StringBuffer 对象
toString() 无 根据这个StringBuffer 创建一个 String
length() 无 StringBuffer 中的字符数量
capacity() 无 返回目前分配的空间大小
ensureCapacity() 用于表示希望容量的一个整数 使StringBuffer 容纳至少希望的空间大小
setLength() 用于指示缓冲区内字串新长度的一个整数 缩短或扩充前一个字符串。如果是扩充,则用 null
值填充空隙
charAt() 表示目标元素所在位置的一个整数 返回位于缓冲区指定位置处的 char
setCharAt() 代表目标元素位置的一个整数以及元素的一个新 char 值 修改指定位置处的值
getChars() 复制的起点和终点,要在其中复制的数组以及目标数组的一个索引 将 char 复制到一个外部数
组。和 String 不同,这里没有getBytes()可供使用
append() 已覆盖:Object,String,char'',特定偏移和长度的char'',boolean,char,int,long,
float,double 将自变量转换成一个字串,并将其追加到当前缓冲区的末尾。若有必要,同时增大缓冲区的
长度
insert() 已覆盖,第一个自变量代表开始插入的位置:Object,String,char'',boolean,char,int,
long,float,double 第二个自变量转换成一个字串,并插入当前缓冲区。插入位置在偏移区域的起点处。
若有必要,同时会增大缓冲区的长度
reverse() 无 反转缓冲内的字符顺序
375
…………………………………………………………Page 377……………………………………………………………
最常用的一个方法是append() 。在计算包含了+和+=运算符的 String 表达式时,编译器便会用到这个方法。
insert()方法采用类似的形式。这两个方法都能对缓冲区进行重要的操作,不需要另建新对象。
12。4。5 字串的特殊性
现在,大家已知道 String 类并非仅仅是Java 提供的另一个类。String 里含有大量特殊的类。通过编译器和
特殊的覆盖或过载运算符+和+=,可将引号字符串转换成一个 String。在本章中,大家已见识了剩下的一种
特殊情况:用同志 StringBuffer 精心构造的“不可变”能力,以及编译器中出现的一些有趣现象。
12。5 总结
由于Java 中的所有东西都是句柄,而且由于每个对象都是在内存堆中创建的——只有不再需要的时候,才会
当作垃圾收集掉,所以对象的操作方式发生了变化,特别是在传递和返回对象的时候。举个例子来说,在C
和C++中,如果想在一个方法里初始化一些存储空间,可能需要请求用户将那片存储区域的地址传递进入方
法。否则就必须考虑由谁负责清除那片区域。因此,这些方法的接口和对它们的理解就显得要复杂一些。但
在Java 中,根本不必关心由谁负责清除,也不必关心在需要一个对象的时候它是否仍然存在。因为系统会为
我们照料一切。我们的程序可在需要的时候创建一个对象。而且更进一步地,根本不必担心那个对象的传输
机制的细节:只需简单地传递句柄即可。有些时候,这种简化非常有价值,但另一些时候却显得有些多余。
可从两个方面认识这一机制的缺点:
(1) 肯定要为额外的内存管理付出效率上的损失(尽管损失不大),而且对于运行所需的时间,总是存在一
丝不确定的因素(因为在内存不够时,垃圾收集器可能会被强制采取行动)。对大多数应用来说,优点显得
比缺点重要,而且部分对时间要求非常苛刻的段落可以用native 方法写成(参见附录A )。
(2) 别名处理:有时会不慎获得指向同一个对象的两个句柄。只有在这两个句柄都假定指向一个“明确”的
对象时,才有可能产生问题。对这个问题,必须加以足够的重视。而且应该尽可能地“克隆”一个对象,以
防止另一个句柄被不希望的改动影响。除此以外,可考虑创建“不可变”对象,使它的操作能返回同种类型
或不同种类型的一个新对象,从而提高程序的执行效率。但千万不要改变原始对象,使对那个对象别名的其
他任何方面都感觉不出变化。
有些人认为 Java 的克隆是一个笨拙的家伙,所以他们实现了自己的克隆方案(注释⑤),永远杜绝调用
Object。clone()方法,从而消除了实现 Cloneable 和捕获 CloneNotSupportException 违例的需要。这一做法
是合理的,而且由于clone()在 Java 标准库中很少得以支持,所以这显然也是一种“安全”的方法。只要不
调用Object。clone(),就不必实现Cloneable 或者捕获违例,所以那看起来也是能够接受的。
⑤:Doug Lea 特别重视这个问题,并把这个方法推荐给了我,他说只需为每个类都创建一个名为duplicate()
的函数即可。
Java 中一个有趣的关键字是byvalue (按值),它属于那些“保留但未实现”的关键字之一。在理解了别名
和克隆问题以后,大家可以想象byvalue 最终有一天会在Java 中用于实现一种自动化的本地副本。这样做可
以解决更多复杂的克隆问题,并使这种情况下的编写的代码变得更加简单和健壮。
12。6 练习
(1) 创建一个myString 类,在其中包含了一个 String 对象,以便用在构建器中用构建器的自变量对其进行
初始化。添加一个 toString()方法以及一个 concatenate()方法,令其将一个 String 对象追加到我们的内部
字串。在myString 中实现 clone()。创建两个 static 方法,每个都取得一个 myString x 句柄作为自己的自
变量,并调用x。concatenate(〃test〃)。但在第二个方法中,请首先调用clone()。测试这两个方法,观察它
们不同的结果。
(2) 创建一个名为Battery (电池)的类,在其中包含一个int,用它表示电池的编号(采用独一无二的标识
符的形式)。接下来,创建一个名为Toy 的类,其中包含了一个Battery 数组以及一个toString,用