在了解这个问题的时候查了不少资料,最有帮助的是这个博文:http://swiftlet.net/archives/1694,看了一段时间,咀嚼了一段时间,写一个经过自己消化的博文,希望能帮到大家。

首先,String,StringBuffer,和StringBuilder都是对char[]的封装,而不同点在于String可以被认为是字符串常量,而StringBuffer,StringBuilder则是字符串变量。

String的成员变量如下:

 private final char value[];
private final int offset;
private final int count;

注意到char value[]是final的,代表着对象一旦被创建就不可改。我们平时常对String执行类似如下操作看起来更改字符串比较自由随意,但是其本身是不断创建新对象的过程:

String a="Hello World";
a=a+"!";
System.out.println(a);
//result: Hello World!

所以,对String执行这种经常修改字符串的操作是效率低下的。

与String不同,StringBuffer和StringBuilder都继承于AbstractStringBuilder,所以我们从AbstractStringBuilder看起

其中成员变量如下

 char value[];
int count;

首先不是final的,其次这个类引入了很多对“容量”控制的方法,很像C++中的<Vector>

例如扩容:当添加字符的长度使得char value[]超出了其本身的最大大小,需要创建一个更大的char[]并将内容复制:

 void expandCapacity(int minimumCapacity)
{
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0)
{
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity)
{
newCapacity = minimumCapacity;
}
char newValue[] = new char[newCapacity];
System.arraycopy(value, 0, newValue, 0, count);
value = newValue;
}

同样,char[]不可能所有容量都被使用,结束标识符同C一样是“\0”;

补长或者截断:

 public void setLength(int newLength)
{
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
if (newLength > value.length)
expandCapacity(newLength);
if (count < newLength)
{
for (; count < newLength; count++)
value[count] = '\0';
} else
{
count = newLength;
}
}

内存复制的方法常用的是:

public static native void arraycopy(Object src, int  srcPos, Object dest, int destPos, int length);

那么StringBuffer和StringBuilder有什么区别:先从StringBuffer和StringBuilder到String的转换看起:

 public String(StringBuffer buffer)
{
synchronized(buffer)
{
this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); }
  }
public String(StringBuilder builder)
{
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

可见,对于StringBuffer而言,处处要考虑其在多线程环境下的并发问题。也就是说,相比于StringBuilder而言,StringBuffer是线程安全的。

另外,关于String的intern方法,是将字符串常量放在一个由String类维护的常量池中。当调用intern 方法时,如果池中已经包含一个等于此String 对象的字符串(是否相等由 equals(Object)方法确定),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并且返回此String 对象的引用。例如:对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()==t.intern()才为true。

最新文章

  1. 【IOS】自定义可点击的多文本跑马灯YFRollingLabel
  2. Android中Bitmap,byte[],Drawable相互转化
  3. 在Ubuntu14.04_ROS_indigo上安装Kinect2驱动和bridge
  4. BAE hibernate c3p0数据库连接池
  5. Linux高级编程--04.GDB调试程序(查看数据)
  6. [Android Pro] Android Support 包里究竟有什么
  7. Java学习笔记——JDK1.7的新特性。
  8. 去除C/C++程序代码中的注释
  9. 让你的WizFi250适应各种气候
  10. 使用Visual Studio 创建可视Web Part部件
  11. iOS画面模糊
  12. 关于JS中变量提升的规则和原理的一点理解(二)
  13. JS中定义对象和集合
  14. Docker技术知识点总结
  15. Filter笔记
  16. Largest Rectangle in a Histogram POJ - 2559 (单调栈)
  17. iOS:百度长语音识别具体的封装:识别、播放、进度刷新
  18. pycharm修改快捷键
  19. fzu2204 dp
  20. 设置webstorm支持ES6语法

热门文章

  1. C++ 系列:C++ 内存布局
  2. CSS - 选择器相关
  3. Python3基础笔记_元组
  4. Flink Checkpoint 问题排查实用指南
  5. Ubuntu16.04安装pcl库
  6. linux系统添加定时任务
  7. swoole是如何实现任务定时自动化调度的?
  8. 表单修饰符.lazy.number.trim
  9. 版本控制git之二 分支 切换分支 创建分支 合并 删除
  10. java基础之BigDecimal类