声明:本博客为原创博客,未经同意。不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(链接为http://blog.csdn.net/bettarwang/article/details/26412497),看代码和提问、讨论都更方便。

首先简单地来梳理一下Java中String、StringBuffer和StringBuilder各自的含义。

1.String类

首先。它是线程安全的,即能够用于多线程编程中。

其次,String类的对象是不可变的,即在定义时就确定了,类似String str="Hello";str+="Java";的语句事实上是生成了新的对象,仅仅是我们未察觉到而已。可是注意在大量的字符串新建对象时消耗就非常可观。这时必须考虑採用StringBuffer或StringBuilder,否则会极大地减少程序的效率。

2.StringBuffer类:

首先,它也是线程安全的。

其次,它是可变类,对它指向的字符串的操作都不会产生新的对象。 每一个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自己主动添加容量。因而它的效率要比String高。

StringBuffer
类最经常使用的两个方法是 append 和 insert 方法,StringBuffer已经重载了这些方法,以接受随意类型的数据,所以小伙伴们。如果strBuffer是StringBuffer的对象。那么像strBuffer.append(3.14f);strBuffer.append(true);这种语句都是全然合法的。

3.StringBuilder类:

首先,它不是线程安全的。即仅仅能用于单线程编程中。

其次。它跟StringBuffer类似,即其对象也是一个可变的字符序列。可是要注意的是它以下几种构造方法:

StringBuilder():创建一个容量为16的StringBuilder对象。

StringBuilder(int
capacity):创建一个容量为capacity的StringBuilder对象;

StringBuilder(String
s):创建一个包括s的StringBuilder对象。同一时候末尾加入16个空元素。

StringBuilder(CharSequence
cs):创建一个包括cs的StringBuilder对象,末尾附加16个空元素;

综上可知。在线程同步方面。String和StringBuffer是线程安全的,而StringBuilder不是线程安全的;在运行效率上,StringBuilder>StringBuffer>String,因而在须要大量的进行字符串操作的单线程场合,应该昼使用StringBuilder以提高效率,在大量进行字符串操作的多线程情形,StringBuffer无疑是最佳的选择。而对于少量的字符串操作的单线程或多线程情形下,使用String则更为简单、方便。

上面对这三个类进行了一下梳理,但这仅仅是基础知识,根本谈不上深刻理解。取这么一个题目不是想哗众取宠。以下就開始结合我自己的一些经历谈一下自己的理解。

我们都知道,String类的对象是不可变的。可是又考虑到Java中”一切皆引用“,以为在函数中传String引用能够实现值的改变。因而经常犯以下这种错误:

import java.util.*;
import java.io.*; public class StringTest
{
private static void treatString(String str)
{
if(str.contains("hello"))
{
str="hello java";
}
else
{
str="enjoy java";
}
} public static void main(String[]args)
{
String str1="hello world";
String str2="study java";
treatString(str1);
treatString(str2); System.out.println(str1);
System.out.println(str2);
}
}

输出结果例如以下图所看到的:

本来期望传递引用从而改变字符串str1和str2的值,可是从输出结果看字符串的值却是根本没有被改变,这是为什么呢?

原来确实传递的也是引用。可是与一般的对象不同,treatString(String)函数并没有对str指向的对象进行改动(或者说并没有在str指向的内存地址上进行改动)。而是新建了一个String对象。可是这个新建的对象却是仅仅有形參指向它,实參并没有指向它。实际上整个过程中实參str都始终还是指向最開始那个对象。所以不难理解为什么会有这种输出结果。

那么假设想要获得一般对象传递引用的效果该怎么办?

非常easy,第一种方法,也是我个人比較推荐的方法,就是返回值String而不是void,即将上面的代码改动为:

import java.util.*;
import java.io.*; public class StringTest
{
//private static void treatString(String str)
private static String treatString(String str)
{
if(str.contains("hello"))
{
str="hello java";
}
else
{
str="enjoy java";
} return str;
} public static void main(String[]args)
{
String str1="hello world";
String str2="study java";
str1=treatString(str1);
str2=treatString(str2); System.out.println(str1);
System.out.println(str2);
}
}

此时输出结果例如以下图所看到的:





显然。此时已经达到了我们预期的目的。

到了这里,我再结合自己的还有一个经历,就是一開始对String.replace(oldChar,newChar);这个函数不熟悉。以为仅仅要调用它就能够实现str的改变(即以为直接str.replace(oldChar,newChar);就能实现str的改变),实际上要利用它的返回值才干改变str,即str=str.replace(oldChar,newChar);才是正确的做法。

另外一种方法,当然就是利用StringBuffer和StringBuilder喽,由于它们是对象可变的嘛。

详细样例到后面再追加。今天先写到这里吧。

晚安啦,小伙伴们!

深刻理解Java中的String、StringBuffer和StringBuilder的差别的更多相关文章

  1. 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

    声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...

  2. Android/Java 中的 String, StringBuffer, StringBuilder的区别和使用

    Android 中的 String, StringBuffer 和 StringBuilder 是移动手机开发中经常使用到的字符串类.做为基础知识是必须要理解的,这里做一些总结. A.区别 可以从以下 ...

  3. 深入理解Java中的String

    一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...

  4. 【转】深入理解Java中的String

    原文链接:http://www.cnblogs.com/xiaoxi/p/6036701.html 一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码 ...

  5. Java中String,StringBuffer与StringBuilder的差别

    String 字符串常量: StringBuffer 字符串变量〈缓冲区〉(线程安全): StringBuilder 字符串变量〈缓冲区〉(非线程安全): 简要的说, String 类型和 Strin ...

  6. 重温java中的String,StringBuffer,StringBuilder类

    不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...

  7. JDK学习---深入理解java中的String

    本文参考资料: 1.<深入理解jvm虚拟机> 2.<大话数据结构>.<大话设计模式> 3.http://www.cnblogs.com/ITtangtang/p/3 ...

  8. 在JAVA中,String,Stringbuffer,StringBuilder 的区别

    首先是,String,StringBuffer的区别 两者的主要却别有两方面,第一是线程安全方面,第二是效率方面 线程安全方面: String  不是线程安全的,这意味着在不同线程共享一个String ...

  9. 深刻理解Java中形參与实參,引用与对象的关系

    声明:本博客为原创博客,未经同意.不得转载! 原文链接为http://blog.csdn.net/bettarwang/article/details/30989755 我们都知道.在Java中,除了 ...

随机推荐

  1. Solr.NET快速入门(二)

    字典映射和动态字段 Solr dynamicFields可以根据用例不同地映射. 它们可以被"静态地"映射,例如,给定: <dynamicField name="p ...

  2. Android网络编程随想录(四)

    前面三篇文章从最基础的TCP,HTTP协议理论开始,然后介绍了在Android的开发中所使用的HttpClient和HttpUrlConnection这两种Http客户端.在本文中,我们一起来学习一下 ...

  3. 全面改造升级内部OA系统

    项目功能集团的OA办公系统,分别是销售管理系统.财务付款系统.原料采购系统.成品采购系统.担保系统和库房管理系统业务现状成品采购系统.库房管理系统.销售管理系统是Access开发的C/S系统,采用本地 ...

  4. JUC集合-BlockingQueue

    BlockingQueue 阻塞队列,支持两个附加操作. 1,在队列为空时,获取元素的线程会等待对列变为非空. 2,在队列为满时,存储元素的线程会等待对列可用. 使用场景: 生产者往对列里添加元素 消 ...

  5. 学习环境搭建2——安装django

    下载django https://www.djangoproject.com/download/ 选择最新的版本Latest release,下载后解压.在含有setup.py的文件夹中执行如下命令: ...

  6. javascript中的原型对象

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. mybatis 高级映射和spring整合之查询缓存(5)

    mybatis 高级映射和spring整合之查询缓存(5) 2.0 查询缓存 2.0.1 什么是查询缓存 mybatis提供缓存,用于减轻数据压力,提高数据库性能. mybatis提供一级缓存和二级缓 ...

  8. EF Code First连接现有数据库

    作为一个初入学习.net MVC4 的新手,想写一写今天碰到的问题,做一个总结. 首先我想利用EF Code First来连接我现有数据库,而不是通过EF Code First来自动生成数据库和表. ...

  9. SDL2源代码分析

    1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...

  10. 【Vue+Node】解决axois请求数据跨域问题

    项目基于Vue前端+Node后台,启动两个服务,请求数据时,端口不一致造成跨域报错: (No 'Access-Control-Allow-Origin' header is present on th ...