- 1、本文档共8页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
初探Java字符串-编程开发技术
初探Java字符串
廉文出处:蔡晓建
String印象
String是java屮的无处不在的类,使用也很简单。初学java,就已经有字符串 是不可变的盖棺定论,解释通常是:它是final的。
不过,String是有字面量这一说法的,这是其他类型所没有的特性(除原牛类 型)。另外,九阳中也冇字符串常量池这个说法,用來存储字符串字面量,不是 在堆上,而是在方法区里边存在的。
字面量和常量池初探
字符串对象内部是用字符数组存储的,那么看下面的例子:
String m 二hello,world;
String n 二hello, world;
String u = new String(m);
String v = new String(hello, world);
这些语旬会发生什么事情?大概是这样的:
会分配一个11长度的char数组,并在常量池分配一个山这个char数组组成的字符 串,然后由m去引用这个字符串。
用n去引用常最池里边的字符串,所以和n引用的是同一个对象。
生成一个新的字符串,但内部的字符数组引用着m内部的字符数组。
同样会生成一个新的字符串,但内部的字符数组引用常量池里边的字符串内部的字 符数组,意思是和u是同样的字符数组。
如杲我们使用一个图来表示的话,情况就大概是这样的(使用虚线只是表示两者 其实没什么特别的关系):
结论就是,m和n是同一个对象,但m,u,v都是不同的对象,但都使用了同样的 字符数组,并且用equal判断的话也会返回true。
我们可以使用反射修改字符数组来验证一下效果,可以试试下而的测试代码:
?Test public void test 1 () throws Exception {
String m 二 〃hello, world;
String n 二hello,world;
String u = new String(m);
String v = new String(/zhello, worldO ;
Field f 二 m. getCleiss(). getDeclaredField(〃value〃); f. setAcccssiblc(true);
char[] cs = (char []) f. get (m);
cs[0] = H;
String p 二 〃Hello, world;
Assert.asscrtEquals(p,m);
Assert? assertEquals(p, n);
Assert.assertEquals(p, u);
Assert.assertEquals(p, v);
}
从上面的例子可以看到,经常说的字符串是不可变的,其实和其他的final类还 是没什么区别,述是引用不可变的意思。虽然String类不开放value,但同样 是可以通过反射进行修改,只是通常没人这么做而已。即使是涉及”修改”的 方法,都是通过产生一个新的字符串对象來实现的,例如replace、toLower concat等。这样做的好处就是让字符串是一个状态不可变类,在多线程操作时 没有后顾之忧。
当然,在字符串修改的时候,会产生一个新的对彖,如果执行很频繁,就会导致 大量对彖的创建,性能问题也就随之而来了。为了应付这个问题,通常我们会 采用StringBuffer或StringBu订der类来处理。
另外,字符串常量通常是在编译的时候就确定好的,定义在类的方法区里边,也 就是说,不同的类,即使用了同样的字符串,述是属于不同的对象。所以才需 要通过引用字符串常量来减少相同的字符串的数量。可以通过下面的代码来测试
class A { public void print() {
System. out? printlnChcllo);
class B {
public void print() { String s = hello;
//修改s的笫一个字符为H
System, out. printin(,,hello/,) ; // 输出 Hello new A(). print () ; // 输出 hello
字符串操作细节
String类内部处理有个字符数组之外,还使用偏移位置offset和长度count,通 过offset和count來确定字符数组的一部分,这部分才是这个字符申的真正的 内容。例如,有substring这个常用方法,看下面的例子:
String m = hello, world;
String u = m. substring(2, 10);
String v 二 u. substring(4, 7);
按照上面的说法,的数据结构就如下图所示:
可以发现,m, n, V是三个不同的字符串对象,但引用的value数组其实是
文档评论(0)