【重走Android之路】【基础篇(二)】【Java面向对象基础】细说String、StringBuffer和StringBuilder
 

1、String

String是Java中的一个final类,主要用于字符串的处理。

1.1 不可变性

String内的字符串是不可变的,每一次修改都会重新生成一个新的String对象实例。
例:
 // 在堆中会创建一个"Hello"字符串实例,把地址赋给对象a
String a = new String("Hello");
// 在堆中又重新创建了一个"World"字符串实例,把新地址赋给对象a
a = new String("World");

经过上述操作,字符串"World"并不是在原字符串"Hello"的空间上修改的,而是重新开辟空间保存"World",然后把新空间的地址赋予a

 

1.2 字符串常量池

字符串常量保存在Java的.class文件常量池中,在编译期已经确定好,在运行期被JVM装载。Java确保一个字符串在常量池中只有一份。
例:
 // 创建引用a,在常量池中增加"Hello"字串,把"Hello"字串的地址赋给a
String a = "Hello";
// 创建引用b,在常量池中寻找"Hello"字串,把"Hello"字串的地址赋给b
String b = "Hello";
// 创建引用c,在常量池中寻找拼接后的"Hello"字串,把"Hello"字串的地址赋给c
String c = "He" + "llo";
// 此时,a、b、c三个对象引用对应的地址都是常量池内"Hello"的地址,所以下面的比较均会返回true
System.out.println(a == b);// true
System.out.println(a == c);// true // 但是下面这种方式不会在常量池中保存
// 创建引用d,在堆中开辟空间存储字串"Hello",把空间地址赋给d
String d = new String("Hello"); // 此时,d对应的地址将是堆内的"Hello"字串地址,而非常量池中"Hello"的地址
System.out.println(a == d);// false

1.3 intern方法

字符串常量池并不是固定不变的,其具有扩展性,使用String.intern()方法便可扩展。intern()方法的作用,是把当前字符串对象的值add到常量池中,如果常量池中已经包含该字符串则返回其在常量池中的地址,如果常量池中不存在该字符串则追加到常量池中同时返回其追加到常量池后的地址。
闲话少说,看例子:
 // 执行扩展,但是引用d的地址并未修改,所以此时比较a和d仍为false
d.intern();
System.out.println(a == d);// false // 执行扩展,把新地址赋给d,由于新地址指向的是常量池中已经存在的"Hello"字串,所以此时a和d的引用地址相同
d = d.intern();
System.out.println(a == d);// true

1.4 参数传递

虽然String是类,属于引用类型,但是前文已经说过,String是一个不可变的字符串对象,所以其作为参数进行传递时和其他引用类型不同:如果参数在方法体内被修改,其原引用的值不会改变。
例:
 static void testParamTrans() {
String param = "Hello World";
User user = new User(0, "Nodin", 23); System.out.println("Before-------------");
System.out.printf("param is %s, user.name is %s\n", param, user.getName()); change(param, user); System.out.println("After------------");
System.out.printf("param is %s, user.name is %s\n", param, user.getName());
} static void change(String param, User user) {
param = "New World";
user.setName("New Name");
}
输出结果:

Before-------------
param is Hello World, user.name
is Nodin
After-------------
param is Hello World, user.name is New
Name
可以看出变量param在被change方法修改前后其值均未发生变化。
 

1.5 有关字符串的比较

 

2、StringBuffer

 
StringBuffer是一个线程安全的字符串序列,类似于一个String缓冲区,缓冲区内的字符串可以修改但是缓冲区本身不可修改。
 
之所以说是线程安全的,是因为StringBuffer的缓冲区在面对多线程请求访问的时候,使用synchronized关键字进行了同步控制,保证同一时刻只有一个线程访问缓冲区。
 
在做字符串拼接时建议使用,特别是在有线程安全考虑的环境。
 
常用的方法包括append、insert、length、toString和delete、deleteCharAt等。
 

3、StringBuilder

 
StringBuilder是StringBuffer的简化版,较StringBuffer轻量级,主要区别在于去除了synchronized关键字控制,即非线程安全。
 
在做字符串拼接时建议使用,特别是单线程字符串拼接。
 
常用方法和StringBuffer一致。
 

4、String、StringBuffer和StringBuilder的区别

 
String、StringBuffer、StringBuilder都是final类,不可被继承,同时都实现了序列化;
StringBuffer和StringBuilder同时继承自AbstractStringBuilder;
StringBuffer线程安全,StringBuilder非线程安全;
String是不可变字符串对象,而StringBuffer和StringBuilder则对应的是字符串缓冲区;
适用环境及效率:
    String:用于简单的字符串操作,大量字符串操作特别是拼接时效率极低;
    StringBuffer:用于字符串拼接,特别是多线程的字符串拼接工作,效率较高;
    StringBuilder:用于单线程下字符串拼接,效率最高。
 

【重走Android之路】【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder的更多相关文章

  1. 【重走Android之路】【Java面向对象基础(三)】面向对象思想

    [重走Android之路][基础篇(三)][Java面向对象基础]面向对象思想   1 面向对象的WWH   1.1 What--什么是面向对象         首先,要理解“对象”.在Thinkin ...

  2. 【重走Android之路】【Java面向对象基础(一)】数据类型与运算符

    [重走Android之路][基础篇(一)][Java面向对象基础]数据类型与运算符   1.数据类型介绍 在Java中,数据类型分为两种:基本数据类型和引用类型. 基本数据类型共8种,见下表: 基本数 ...

  3. 【重走Android之路】【番外篇】关于==和equals

    [重走Android之路][番外篇]关于==和equals   在实际的编程当中,经常会使用==和equals来判断变量是否相同.但是这两种比较方式也常常让人搞得云里雾里摸不着头脑.下面是我个人做的总 ...

  4. 【重走Android之路】【路线篇(二)】知识点归纳

    [重走Android之路][路线篇(二)]知识点归纳   参考:http://blog.csdn.net/xujing81/article/details/7313507   第一阶段:Java面向对 ...

  5. 【重走Android之路】【开篇】序

    [重走Android之路][开篇]   [序]         本人Nodin,偶尔也叫MoNodin,朋友们都喜欢叫我丁,还有个笔名叫陌上幽人,文艺时叫恋风,发奋时叫不肯腐烂的土壤...也许你觉得我 ...

  6. 【重走Android之路】【番外篇】有关于null的一些知识点

    [重走Android之路][番外篇]有关于null的一些知识点   1.首先,到底什么是null? null是Java中的一个关键字,用于表示一个空对象引用,但其本身并不是任何类型也不是属于任何对象. ...

  7. 【重走Android之路】【路线篇(一)】路线图

    总结归纳了J2SE和Android的知识点,自己制订了一套详细的路线图,其中肯定有考虑不全和不合适的地方,欢迎各位大牛批评指正.   详细路线图如下:  

  8. java面向对象基础(二)

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  9. Java面向对象基础二

    1.对象的用法 2.多对象的创建方法 3.匿名对象的创建和用法

随机推荐

  1. 一些常用到的Centos命令

    CentOS常用命令在我们的使用中,经常被使用.所以,我们对一些经常使用又很重要的CentOS常用命令进行了全面的整理.下面,就来介绍这些CentOS常用命令. 一:使用CentOS常用命令查看cpu ...

  2. pcxFirefox 自定义

    便携特性(ini设置)     把与firefox.exe同文件夹的tmemutil-sample.ini 改名为tmemutil.ini,设置如下: Portable=1 #便携式 Portable ...

  3. 临时文档9--dfs

    #include<iostream> #include<stdio.h> #include<math.h> #include<string.h> usi ...

  4. hdu 1548 A strange lift 宽搜bfs+优先队列

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1548 There is a strange lift.The lift can stop can at ...

  5. 【BZOJ】【1150】【CTSC2007】数据备份Backup

    堆/贪心 一共N-1个元素……用堆维护最大值,取了第x个元素以后,插入v[x-1]+v[x+1]-v[x]这个元素,如果再取这个新元素就表示不取x,而取x-1和x+1……大概就是这种“带反悔”的思路吧 ...

  6. Nodejs Express 4.X 中文API 2--- Request篇

    相关阅读: Express 4.X API 翻译[一] --  Application篇 Express4.XApi 翻译[二] --  Request篇 Express4.XApi 翻译[三] -- ...

  7. 百度Hi之CSRF蠕虫攻击

    漏洞起因:百度是国内最大的中文搜索引擎.同时百度也提供了百度空间.百度贴吧等BLOG社区服务,拥有海量的用户群,号称全球最大中文社区. 80sec发现过百度产品一系列的安全漏洞,其中一些问题得到了有效 ...

  8. 功率单位mW 和 dBm 的换算

    无线电发射机输出的射频信号,通过馈线(电缆)输送到天线,由天线以电磁波形式辐射出去.电磁波到达接收地点后,由天线接收下来(仅仅接收很小很小一部分功率),并通过馈线送到无线电接收机.因此在无线网络的工程 ...

  9. Codeforces Round #243 (Div. 1) A题

    http://codeforces.com/contest/425/problem/A 题目链接: 然后拿出这道题目是很多人不会分析题目,被题目吓坏了,其中包括我自己,想出复杂度,一下就出了啊!真是弱 ...

  10. ASP.NET中数据棒图,饼图,柱状图的实现

    Web中绘制图形的方法大致有: 1. VML方式:功能强大,但是非常麻烦. 推荐:http://www.elook.net.cn/vml/ 2.使用控件:Dandus, Aspose.chart,Co ...