【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder

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

1、String

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

1.1 不可变性

String内的字符串是不可变的,每一次修改都会重新生成一个新的String对象实例。

例:

1 // 在堆中会创建一个"Hello"字符串实例,把地址赋给对象a
2 String a = new String("Hello");
3 // 在堆中又重新创建了一个"World"字符串实例,把新地址赋给对象a
4 a = new String("World");

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

1.2 字符串常量池

字符串常量保存在Java的.class文件常量池中,在编译期已经确定好,在运行期被JVM装载。Java确保一个字符串在常量池中只有一份。

例:

 1 // 创建引用a,在常量池中增加"Hello"字串,把"Hello"字串的地址赋给a
 2 String a = "Hello";
 3 // 创建引用b,在常量池中寻找"Hello"字串,把"Hello"字串的地址赋给b
 4 String b = "Hello";
 5 // 创建引用c,在常量池中寻找拼接后的"Hello"字串,把"Hello"字串的地址赋给c
 6 String c = "He" + "llo";
 7 // 此时,a、b、c三个对象引用对应的地址都是常量池内"Hello"的地址,所以下面的比较均会返回true
 8 System.out.println(a == b);// true
 9 System.out.println(a == c);// true
10
11 // 但是下面这种方式不会在常量池中保存
12 // 创建引用d,在堆中开辟空间存储字串"Hello",把空间地址赋给d
13 String d = new String("Hello");
14
15 // 此时,d对应的地址将是堆内的"Hello"字串地址,而非常量池中"Hello"的地址
16 System.out.println(a == d);// false

1.3 intern方法

字符串常量池并不是固定不变的,其具有扩展性,使用String.intern()方法便可扩展。intern()方法的作用,是把当前字符串对象的值add到常量池中,如果常量池中已经包含该字符串则返回其在常量池中的地址,如果常量池中不存在该字符串则追加到常量池中同时返回其追加到常量池后的地址。

闲话少说,看例子:

1 // 执行扩展,但是引用d的地址并未修改,所以此时比较a和d仍为false
2 d.intern();
3 System.out.println(a == d);// false
4
5 // 执行扩展,把新地址赋给d,由于新地址指向的是常量池中已经存在的"Hello"字串,所以此时a和d的引用地址相同
6 d = d.intern();
7 System.out.println(a == d);// true

1.4 参数传递

虽然String是类,属于引用类型,但是前文已经说过,String是一个不可变的字符串对象,所以其作为参数进行传递时和其他引用类型不同:如果参数在方法体内被修改,其原引用的值不会改变。

例:

 1 static void testParamTrans() {
 2     String param = "Hello World";
 3     User user = new User(0, "Nodin", 23);
 4
 5     System.out.println("Before-------------");
 6     System.out.printf("param is %s, user.name is %s\n", para, user.getName());
 7
 8     change(param, user);
 9
10     System.out.println("After------------");
11     System.out.printf("param is %s, user.name is %s\n", para, user.getName());
12 }
13
14 static void change(String param, User user) {
15     param = "New World";
16     user.setName("New Name");
17 }

输出结果:

Before-------------
param is Hello World, user.name
is Nodin
After-------------

param is Hello World, user.name is New
Name

可以看出变量param在被change方法修改前后其值均未发生变化。

1.5 有关字符串的比较

详见博文:【喵"的Android之路】【番外篇】关于==和equals

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:用于单线程下字符串拼接,效率最高。

本文系Nodin原创,转载请注明出处!http://www.cnblogs.com/monodin/p/3841188.html

【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder,布布扣,bubuko.com

时间: 2024-10-13 01:10:47

【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder的相关文章

java面向对象基础(二)

*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hljs-comment, .hljs-template_comment, .diff .hljs-header, .hljs-javadoc { color: #998; font-style: italic; } .hljs-keyword, .css .rule .hljs-keyword, .h

Java面向对象基础二

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

【Java面向对象基础(一)】数据类型与运算符

[喵"的Android之路][基础篇(一)][Java面向对象基础]数据类型与运算符 1.数据类型介绍 在Java中,数据类型分为两种:基本数据类型和引用类型. 基本数据类型共8种,见下表: 基本数据类型 字节数 二进制位数 最小值 最大值 默认值 byte 1 8-bit -2^7 +2^7 - 1 0 short 2 16-bit -2^15 +2^15 - 1 0 int 4 32-bit -2^31 +2^31 - 1 0 long 8 64-bit -2^63 +2^63 - 1 0

【Java面向对象基础(三)】面向对象思想

[喵"的Android之路][基础篇(三)][Java面向对象基础]面向对象思想 1 面向对象的WWH 1.1 What--什么是面向对象 首先,要理解“对象”.在Thinking in Java中提到“Everything is an object”,即万物皆对象.这里的“对象”指的是任何实体或者任何可以当作实体看待的“虚幻的事物”.比如现实中的人(男人.女人.老人.小孩而...).动物(大象.狮子.猴子...).桌子.凳子.汽车.ATM机等等,也可以使看不见摸不着的空气(氧气.二氧化碳.氮气

一大波Java来袭(四)String类、StringBuilder类、StringBuffer类对比

本文主要介绍String类.StringBuffer类.StringBuilder类的区别  : 一.概述 (一)String 字符串常量,但是它具有不可变性,就是一旦创建,对它进行的任何修改操作都会创建一个新的字符串对象. (二)StringBuffer 字符串可变量,是线程安全的,和StringBuilder类提供的方法完全相同. 区别在于StringBuffer每个方法中前面添加了"synchronized",保证其是线程安全的. (三)StringBuilder 字符串可变量,

【Java】String,StringBuffer与StringBuilder的区别??

String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以

Java杂谈之StringBuffer----兼带String,StringBuffer,StringBuilder的区别

在Java中,用到最多的当属String类型的数据了 而这一点就要涉及String , StringBuffer , StringBuilder这三大类 下面主要来比较一下String和StringBuffer的区别,因为StringBuffer和StringBuilder 太相似,所以就不拿来比较了. 提及一下,StringBuffer和StringBuilder的区别 从安全性来说,StringBuffer更安全,StringBuffer主打线程安全 从执行效率来说,StringBuilde

Java String, StringBuffer和StringBuilder实例

1- 分层继承2- 可变和不可变的概念3- String3.1- 字符串是一个非常特殊的类3.2- String 字面值 vs. String对象3.3- String的方法3.3.1- length()3.3.2- concat(String)3.3.3- indexOf(..)3.3.4- substring(..)3.3.5- replace3.3.6- 其它实例4- StringBuffer vs StringBuilder 1- 分层继承 当使用文本数据时,Java提供了三种类别,包括

【JAVA】辨析:String,StringBuffer与StringBuilder

参考链接: CSDN:图析:String,StringBuffer与StringBuilder的区别 1. Java String 类:字符串常量 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 需要注意的是,String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间. String操作时内存变化的图: 2. StringBuffer 和 Str