也说String。

  • String:不可变字符序列。
  • StringBuffer:线程安全的可变字符序列。
  • StringBuilder:StringBuffer的非线程安全实现,JDK1.5+。
public final class String {
private final char value[];
public String(String original) {
// 把原字符串original切分成字符数组并赋给value[];
}
} //StringBuffer
public final class StringBuffer extends AbstractStringBuilder {
char value[]; //继承了父类AbstractStringBuilder中的value[]
public StringBuffer(String str) {
super(str.length() + 16); //继承父类的构造器,并创建一个大小为str.length()+16的value[]数组
append(str); //将str切分成字符序列并加入到value[]中
}
}

1    常量池

在Java源代码中的每一个字面值字符串,都会在编译成class文件阶段,形成标志号为8(CONSTANT_String_info)的常量表。 当JVM加载 class文件的时候,会为对应的常量池建立一个内存数据结构(StringTable,它是一个hashtable,key是字符串的hashcode,value是字符串的引用地址。),并存放在方法区中。同时JVM会自动为CONSTANT_String_info常量表中的字符串常量字面值在堆中创建新的String对象(intern字符串对象)。然后把CONSTANT_String_info常量表的入口地址转变成这个堆中String对象的直接地址(常量池解析)。

示例:

String sc="ab"+"cd";
String sd="abcd";
System.out.println(sc==sd); //true,在应用启动完成时就已经加载至常量池了

2    StringBuilder与String+

String sa = "a";
String s = sa + "b";

javap -c查看虚拟机指令:

       0: ldc           #2                  // String a
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6 // String b
16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_2
23: return

由上可以看到,String+实际上的操作就是new StringBuilder().append().append….toString()。因此如下方法不会引起效率问题(除非链接字符串较长时,因为String+操作默认初始化大小16导致append时多次resize):

String method(String sa) {
return sa + "b";
}

一般所说的String+效率低下的主要产生在如下情况:

String method(String sa) {
for (int i=0; i<100; i++) {
sa += "b";
}
return sa;
}

每做一次+就产生一个StringBuilder对象,然后append后丢掉。下次循环重新产生一个StringBuilder对象。如果我们直接使用StringBuilder对象全程append的话,就可以节省N-1次创建与销毁对象的时间。

通过上面的说明,我们可以知道如下结果:

String sa = "ab";
String sb = "cd";
String sab = sa+sb;
String s = "abcd";
System.out.println(sab==s); // false

3    String.intern

String.intern可以将一个String类的保存到一个全局StringTable表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中。

通过这个方法我们可以测试常量池到底占用JVM的哪一区域。

String、StringBuffer、StringBuilder的更多相关文章

  1. Java中String、StringBuffer、StringBuilder区别与理解

    一.先比较String.StringBuffer.StringBuilder变量的HashCode值 使用System.out.println(obj.hashcode())输出的时对象的哈希码, 而 ...

  2. String、StringBuffer、StringBuilder的区别

    在日常开发过程中String字符串估计是被用到最多的变量了,最近看了一些String.StringBuffer和StringBuilder的东西,三者都可以对字符串进行操作,他们究竟有什么区别,以及适 ...

  3. String、StringBuffer、StringBuilder的一些小经验……

    一说String.StringBuffer和StringBuilder,想必大家都很熟悉,这三者经常在我们的面试题中出现,我也是看到了关于这三个的经典面试题,才触动了我之前工作中的一些经历,故而根据我 ...

  4. java中String、StringBuffer、StringBuilder的区别

    java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1.可变与不可 ...

  5. String、StringBuffer与StringBuilder之间区别[全屏看文]

    String.StringBuffer与StringBuilder之间区别[全屏看文]   最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,S ...

  6. 浅析String、StringBuffer、StringBuilder的区别以及性能区别

    前奏: 比较三者之间的区别在与区别他们做相同的事情的时候的区别,那就是在我们常见的拼接字符串的时候,StringBuffer.StringBuilder调用的是appende()方法,而String很 ...

  7. [drp 2]String、StringBuffer和StringBuilder的区别

    导读:在实际运用了,我们会频繁的用到string.stringBuffer和stringBuilder这三个东西,那么,他们之间的区别是什么呢.本文主要是从拼写SQL语句的角度,来阐释他们之间的区别! ...

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

    [重走Android之路][基础篇(二)][Java面向对象基础]细说String.StringBuffer和StringBuilder   1.String String是Java中的一个final ...

  9. 深度学习String、StringBuffer、StringBuilder

    相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffer这几个类,分析它 ...

  10. 提高你的Java代码质量吧:正确使用String、StringBuffer、StringBuilder

    一.建议  CharSequence接口有三个实现类与字符串相关:String.StringBuffer.StringBuilder,虽然它们都与字符串相关,但是其处理机制不同. 根据不同的场景,建议 ...

随机推荐

  1. 从 mian 函数开始一步一步分析 nginx 执行流程(一)

    如不做特殊说明,本博客所使用的 nginx 源码版本是 1.0.14,[] 中是代码所在的文件! 我们先贴出 main 函数的部分代码: [core/nginx.c] int ngx_cdecl ma ...

  2. 龙芯8089_D安装debian 8 iessie

    参考官方文档:https://wiki.debian.org/DebianYeeloong/HowTo/Install 下载网络引导文件后使用tftpd建立ftfp服务器,然后使用PMON tftp来 ...

  3. [Git] Github客户端上publish后一直转圈,web上未上传成功

    连续试了几次,publish后一直处于publish状态,点击其它repositories再点回来就没动静了,也看不到Sys按钮...最后发现,是要等很久才会成功,天朝的网络伤不起

  4. openStack云平台虚拟桌面galera mysql 3节点集群实例实战 调试完成

    被复制节点: /usr/local/mysql/bin/mysqld_safe --wsrep_cluster_address=gcomm:// >/dev/null &复制节点01: ...

  5. SQL第二课-创建数据表

    查看有多少数据库 SHOW DATABASES; 进入数据库:USE <数据库名> 举例:USE test;//进入test数据库 查看当前进入的是哪个数据库 SELECT DATABAS ...

  6. [置顶] IOS 基础入门教程

    IOS 基础入门教程 教程列表: IOS 简介 IOS环境搭建 Objective C 基础知识 创建第一款iPhone应用程序 IOS操作(action)和输出口(Outlet) iOS - 委托( ...

  7. 用code workshop取代code review

    Box Tech Blog » Effective learning through code workshops介绍了Box如何用code workshop而不是code review的形式来改善代 ...

  8. .net 4中的pInvokeStackImbalance MDA默认是开启的

    今天把我之前发的一个小工具FreeEverything(基于everything的一个简易磁盘清理工具)升级到了.net framework 4.5,并且去掉了对mvvmlight的依赖.结果在测试运 ...

  9. mount命令以及mount ntfs硬盘权限权限与显示的问题 分类: shell ubuntu 2014-11-08 18:29 148人阅读 评论(0) 收藏

    sudo mount -t 文件系统类型 -o 可设置选项 设备路经 访问路经 #常用文件类型如下: iso9660 光驱文件系统, vfat fat/fat32分区, ntfs ntfs分区, sm ...

  10. SqlServer快捷键整理

    一:sp_helptext 对象 1.Ctrl+D 表格显示 2.Ctrl+T 文本显示(含格式)