String与StringBuffer的区别,以及两种方式创建字符串对象的区别。

要理解 java中String的运作方式,必须明确一点:String是一个非可变类(immutable)。什么是非可变类呢?简单说来,非可变类的实例是不能被修改的,每个实例中包含的信息都必须在该实例创建的时候就提供出来,并且在对象的整个生存周期内固定不变。java为什么要把String设计为非可变类呢?你可以问问 james Gosling :)。但是非可变类确实有着自身的优势,如状态单一,对象简单,便于维护。其次,该类对象对象本质上是线程安全的,不要求同步。此外用户可以共享非可变对象,甚至可以共享它们的内部信息。(详见《Effective java》item 13)。String类在java中被大量运用,甚至在class文件中都有其身影,因此将其设计为简单轻便的非可变类是比较合适的。

  一、创建。

  好了,知道String是非可变类以后,我们可以进一步了解String的构造方式了。创建一个Stirng对象,主要就有以下两种方式:

  java 代码

  String str1 = new String("abc");

  Stirng str2 = "abc";

  虽然两个语句都是返回一个String对象的引用,但是jvm对两者的处理方式是不一样的。对于第一种,jvm会马上在heap中创建一个String对象,然后将该对象的引用返回给用户。对于第二种,jvm首先会在内部维护的strings pool中通过String的 equels 方法查找是对象池中是否存放有该String对象,如果有,则返回已有的String对象给用户,而不会在heap中重新创建一个新的String对象;如果对象池中没有该String对象,jvm则在heap中创建新的String对象,将其引用返回给用户,同时将该引用添加至strings pool中。注意:使用第一种方法创建对象时,jvm是不会主动把该对象放到strings pool里面的,除非程序调用 String的intern方法。看下面的例子:

  java 代码

  String str1 = new String("abc"); //jvm 在堆上创建一个String对象

  //jvm 在strings pool中找不到值为“abc”的字符串,因此

  //在堆上创建一个String对象,并将该对象的引用加入至strings pool中

  //此时堆上有两个String对象

  Stirng str2 = "abc";

  if(str1 == str2){

  System.out.println("str1 == str2");

  }else{

  System.out.println("str1 != str2");

  }

  //打印结果是 str1 != str2,因为它们是堆上两个不同的对象

  String str3 = "abc";

  //此时,jvm发现strings pool中已有“abc”对象了,因为“abc”equels “abc”

  //因此直接返回str2指向的对象给str3,也就是说str2和str3是指向同一个对象的引用

  if(str2 == str3){

  System.out.println("str2 == str3");

  }else{

  System.out.println("str2 != str3");

  }

  //打印结果为 str2 == str3

  再看下面的例子:

  java 代码

  String str1 = new String("abc"); //jvm 在堆上创建一个String对象

  str1 = str1.intern();

  //程序显式将str1放到strings pool中,intern运行过程是这样的:首先查看strings pool

  //有没“abc”对象的引用,没有,则在堆中新建一个对象,然后将新对象的引用加入至

  //strings pool中。执行完该语句后,str1原来指向的String对象已经成为垃圾对象了,随时会

  //被GC收集。

  //此时,jvm发现strings pool中已有“abc”对象了,因为“abc”equels “abc”

  //因此直接返回str1指向的对象给str2,也就是说str2和str1引用着同一个对象,

  //此时,堆上的有效对象只有一个。

  Stirng str2 = "abc";

  if(str1 == str2){

  System.out.println("str1 == str2");

  }else{

  System.out.println("str1 != str2");

  }

  //打印结果是 str1 == str2

  为什么jvm可以这样处理String对象呢?就是因为String的非可变性。既然所引用的对象一旦创建就永不更改,那么多个引用共用一个对象时互不影响。

  二、串接(Concatenation)。

  java程序员应该都知道滥用String的串接操作符是会影响程序的性能的。性能问题从何而来呢?归根结底就是String类的非可变性。既然String对象都是非可变的,也就是对象一旦创建了就不能够改变其内在状态了,但是串接操作明显是要增长字符串的,也就是要改变String的内部状态,两者出现了矛盾。怎么办呢?要维护String的非可变性,只好在串接完成后新建一个String 对象来表示新产生的字符串了。也就是说,每一次执行串接操作都会导致新对象的产生,如果串接操作执行很频繁,就会导致大量对象的创建,性能问题也就随之而来了。

  为了解决这个问题,jdk为String类提供了一个可变的配套类,StringBuffer。使用StringBuffer对象,由于该类是可变的,串接时仅仅时改变了内部数据结构,而不会创建新的对象,因此性能上有很大的提高。针对单线程,jdk 5.0还提供了StringBuilder类,在单线程环境下,由于不用考虑同步问题,使用该类使性能得到进一步的提高。

  三、String的长度

  我们可以使用串接操作符得到一个长度更长的字符串,那么,String对象最多能容纳多少字符呢?查看String的源代码我们可以得知类String中是使用域 count 来记录对象字符的数量,而count 的类型为 int,因此,我们可以推测最长的长度为 2^32,也就是4G。

  不过,我们在编写源代码的时候,如果使用 Sting str = "aaaa";的形式定义一个字符串,那么双引号里面的ASCII字符最多只能有 65534 个。为什么呢?因为在class文件的规范中, CONSTANT_Utf8_info表中使用一个16位的无符号整数来记录字符串的长度的,最多能表示 65536个字节,而java class 文件是使用一种变体UTF-8格式来存放字符的,null值使用两个字节来表示,因此只剩下 65536- 2 = 65534个字节。也正是变体UTF-8的原因,如果字符串中含有中文等非ASCII字符,那么双引号中字符的数量会更少(一个中文字符占用三个字节)。如果超出这个数量,在编译的时候编译器会报错。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java字符串操作大全,适合初学者,浅显易懂 部JAVA字符串操作 2008-07-11 15:39:42| 分类: JAVA | 标签: |字号大中小 订阅 . JAVA字符串的方法 String a = "53c015"; //Integer.parseInt(s, radix) radix设置为10,表示10进制,16表示16进制啦 int i = Integer.parseInt(a, 16); 1、length() 字符串的长度   例:char chars[]={'a','b'.'c'};     String s=new String(chars);     int len=s.length(); 2、charAt() 截取一个字符   例:char ch;     ch="abc".charAt(1); 返回'b' 3、getChars() 截取多个字符   void getChars(int sourceStart,int sourceEnd,char target[],int targetStart)   sourceStart指定了子串开始字符的下标,sourceEnd指定了子串结束后的下一个字符的下标。因此,子串包含从sourceStart到sourceEnd-1的字符。接收字符的数组由target指定,target中开始复制子串的下标值是targetStart。   例:String s="this is a demo of the getChars method.";     char buf[]=new char[20];     s.getChars(10,14,buf,0); 4、getBytes()   替代getChars()的一种方法是将字符存储在字节数组中,该方法即getBytes()。 5、toCharArray() 6、equals()和equalsIgnoreCase() 比较两个字符串 7、regionMatches() 用于比较一个字符串中特定区域与另一特定区域,它有一个重载的形式允许在比较中忽略大小写。   boolean regionMatches(int startIndex,String str2,int str2StartIndex,int numChars)   boolean regionMatches(boolean ignoreCase,int startIndex,String str2,int str2StartIndex,int numChars) 8、startsWith()和endsWith()   startsWith()方法决定是否以特定字符串开始,endWith()方法决定是否以特定字符串结束 9、equals()和==   equals()方法比较字符串对象中的字符,==运算符比较两个对象是否引用同一实例。   例:String s1="Hello";     String s2=new String(s1);     s1.eauals(s2); //true     s1==s2;//false 10、compareTo()和compareToIgnoreCase() 比较字符串 11、indexOf()和lastIndexOf()   indexOf() 查找字符或者子串第一次出现的地方。   lastIndexOf() 查找字符或者子串是后一次出现的地方。 12、substring()   它有两种形式,第一种是:String substring(int startIndex)          第二种是:String substring(int startIndex,int endIndex) 13、concat() 连接两个字符串 14 、replace() 替换   它有两种形式,第一种形式用一个字符在调用字符串中所有出现某个字符的地方进行替换,形式如下:   String replace(char original,char replacement)   例如:String s="Hello".replace('l','w');   第二种形式是用一个字符序列替换另一个字符序列,形式如下:   String replace(CharSequence original,CharSequence replacement) 15、trim() 去掉起始和结尾的空格 16、valueOf() 转换为字符串 17、toLowerCase() 转换为小写 18、toUpperCase() 转换为大写 19、StringBuffe
本书为中南大学精品教材立项项目,分为上下两篇共21章,涵盖了面向对象技术中Java开发环境配置、程序设计基础、面向对象原理以及UML的知识。本书使用的开发环境是JDK 1.6+Eclipse 3.3+Rational Rose 2003,逐步引领读者从基础到各个知识点进行学习。全书内容由浅入深,并辅以大量的实例说明,书本阶段性地提供了一些实验指导。 本书提供了所有实例的源代码以及开发过程中用到的软件下载地址,供读者学习参考使用。 本书为学校教学量身定做,供高校面向对象技术相关课程使用,对于缺乏项目实战经验的程序员来说可用于快速积累项目开发经验。 本书是中南大学精品教材建设中的一本特色教材,为高校计算机相关专业提供面向对象技术和UML的讲解。本书采用Java语言进行描述,针对Java技术标准编程进行详细的讲解,以简单通俗易懂的案例,逐步引领读者从基础到各个知识点进行学习。本书涵盖了JavaSE开发环境配置、程序设计基础、面向对象相关技术、常用API、UML基础知识。在章节中穿插了上机习题,并提供了答案,用于对该章内容进行阶段性总结演练。 作者长期从事教学工作,积累了丰富的经验,其“实战教学法”取得了很好的效果。本书适合教学。书中章节安排适当,将习题融于讲解的过程中,教师可以根据情况选用,也可以进行适当增减。 本书的知识体系结构如下所示,遵循了循序渐进的原则,逐步引领读者从基础到各个知识点进行学习。 上篇面向对象技术 第1章Java入门 第2章程序设计基础: 变量及其运算 第3章程序设计基础: 流程控制和数组 第4章实验指导1 第5章类、对象和成员 第6章封装 第7章继承和多态 第8章实验指导2 第9章异常处理 第10章Java常用API 第11章Java IO操作 第12章多线程开发 第13章反射技术 第14章实验指导3 下篇UML 第15章UML入门 第16章用例图 第17章类图和对象图 第18章实验指导4 第19章顺序图、协作图、状态图和活动图 第20章包图、构件图和部署图 第21章实验指导5 本书提供了全书所有实例的源代码,供读者学习参考使用,所有程序均经过了作者精心的调试。 由于时间仓促和作者水平有限,书中的错误和不妥之处敬请读者批评指正。 有关本书的意见反馈和咨询,读者可在清华大学出版社相关版块中与作者进行交流。 郭克华 2013年11月 目录 上篇面向对象技术 第1章Java入门 1.1认识Java 1.1.1认识编程语言 1.1.2Java的来历 1.1.3Java为什么流行 1.1.4Java的三个版本 1.1.5编程前的准备工作 1.2安装JDK 1.2.1获取JDK 1.2.2安装JDK步骤 1.2.3安装目录介绍 1.2.4环境变量设置 1.3开发第一个Java程序 1.3.1如何编写源代码 1.3.2如何将源代码编译成.class文件 1.3.3如何执行.class文件 1.3.4新手常见错误 1.4用Eclipse开发Java程序 1.4.1Eclipse的概念 1.4.2安装Eclipse 1.4.3如何建立项目 1.4.4如何开发Java程序 1.4.5如何维护项目 1.5小结 第2章程序设计基础:变量及其运算 2.1认识变量 2.1.1变量的定义 2.1.2变量有哪些类型 2.2如何使用变量 2.2.1如何使用整型变量 2.2.2如何使用浮点型变量 2.2.3如何使用字符型变量 2.2.4如何使用布尔型变量 2.2.5基本数据类型之间的类型转换 2.2.6基本数据类型和字符串之间的转换 2.2.7变量的作用范围 2.3注释的书写 2.4Java中的运算 2.4.1算术运算 2.4.2赋值运算 2.4.3关系运算 2.4.4逻辑运算 2.4.5运算符的优先级 2.5小结 第3章程序设计基础:流程控制和数组 3.1判断结构 3.1.1为什么需要判断结构 3.1.2if结构 3.1.3switch结构 3.2认识循环结构 3.2.1为什么需要循环结构 3.2.2while循环 3.2.3dowhile循环 3.2.4for循环 3.2.5循环嵌套 3.2.6break和continue 3.3数组 3.3.1为什么需要数组 3.3.2如何定义数组 3.3.3如何使用数组 3.3.4数组的引用性质 3.3.5数组的应用 3.3.6多维数组 3.4小结 第4章实验指导1 4.1关于变量和数据类型的实践 4.2流程控制和数组的综合实践 第5章类、对象和成员 5.1认识类和对象 5.1.1为什么需要类 5.1.2如何定义类 5.1.3如何使用类实例化对象 5.1.4如何访问对象中的成员变量 5.1.5对象的引用性质 5.2认识成员函数 5.2.1为什么需要函数 5.2.2如何定义和使用成员函数 5.2.3函数参数的传递 5.2.4认识函数重载 5.3认识构造函数 5.3.1为什么需要构造函数 5.3.2如何定义和使用构造函数 5.4静态变量和静态函数 5.4.1为什么需要静态变量 5.4.2静态变量的常见应用 5.4.3认识静态函数 5.4.4静态代码块 5.5小结 第6章封装 6.1使用封装 6.1.1为什么需要封装 6.1.2如何实现封装 6.2使用包 6.2.1为什么需要包 6.2.2如何将类放在包中 6.2.3如何访问包中的类 6.3使用访问控制修饰符 6.3.1什么是访问控制修饰符 6.3.2类的访问控制修饰符 6.3.3成员的访问控制修饰符 6.4使用类中类 6.5小结 第7章继承和多态 7.1使用继承 7.1.1为什么需要继承 7.1.2如何实现继承 7.1.3继承的底层本质 7.2成员的覆盖 7.2.1什么是成员覆盖 7.2.2成员覆盖有何作用 7.3使用多态性 7.3.1什么是多态 7.3.2如何使用多态性 7.3.3父子类对象的类型转换 7.4抽象类和接口 7.4.1为什么需要抽象类 7.4.2为什么需要接口 7.5其他内容 7.5.1final关键字 7.5.2Object类 7.6一些工具的使用 7.6.1将字节码打包发布 7.6.2文档的使用 7.7小结 第8章实验指导2 8.1单例模式的设计 8.1.1需求简介 8.1.2不用单例模式的效果 8.1.3最原始的单例模式 8.1.4首次改进 8.1.5再次改进 8.1.6思考题 8.2利用继承和多态扩充程序功能 8.2.1需求简介 8.2.2实现方法 8.2.3出现的问题 8.2.4改进 8.2.5测试 第9章异常处理 9.1认识异常 9.1.1生活中的异常 9.1.2软件中的异常 9.1.3为什么要处理异常 9.1.4异常机理 9.1.5常见异常 9.2异常的就地捕获 9.2.1为什么要就地捕获 9.2.2如何就地捕获异常 9.2.3如何捕获多种异常 9.2.4用finally保证安全性 9.3异常的向前抛出 9.3.1为什么要向前抛出 9.3.2如何向前抛出 9.4自定义异常 9.4.1为什么需要自定义异常 9.4.2如何自定义异常 9.5小结 第10章Java常用API 10.1数值运算 10.1.1用Math类实现数值运算 10.1.2实现随机数 10.2用String类进行字符串处理 10.3用StringBuffer类进行字符串处理 10.4基本数据类型的包装类 10.4.1认识包装类 10.4.2通过包装类进行数据转换 10.5认识Java集合 10.5.1为什么需要集合 10.5.2Java中的集合 10.6使用一维集合 10.6.1认识一维集合 10.6.2使用List集合 10.6.3使用Set集合 10.6.4使用Collections类对集合进行处理 10.6.5使用泛型简化集合操作 10.7Java中的二维集合 10.7.1使用Map集合 10.7.2使用Hashtable和Properties 10.8小结 第11章Java IO操作 11.1认识IO操作 11.2用File类操作文件 11.2.1认识File类 11.2.2使用File类操作文件 11.2.3使用File类操作目录 11.3字节流的输入输出 11.3.1认识字节流 11.3.2如何读写文件 11.3.3如何读写对象 11.4字符流的输入输出 11.4.1认识字符流 11.4.2如何读写文件 11.4.3如何进行键盘输入 11.5和IO操作相关的其他类 11.5.1用RandomAccessFile类进行文件读写 11.5.2使用Properties类 11.6小结 第12章多线程开发 12.1认识多线程 12.1.1为什么需要多线程 12.1.2继承Thread类开发多线程 12.1.3实现Runnable接口开发多线程 12.1.4两种方法有何区别 12.2控制线程运行 12.2.1为什么要控制线程运行 12.2.2传统方法的安全问题 12.2.3如何控制线程的运行 12.3线程同步安全 12.3.1什么是线程同步 12.3.2一个有问题的案例 12.3.3如何解决 12.3.4小心线程死锁 12.4认识定时器 12.4.1为什么需要定时器 12.4.2如何使用定时器 12.5小结 第13章反射技术 13.1为什么要学习反射 13.1.1引入配置文件 13.1.2配置文件遇到的问题 13.2认识Class类 13.2.1什么是Class类 13.2.2如何获取一个类对应的Class对象 13.2.3如何获取类中的成员信息 13.3通过反射机制访问对象 13.3.1如何实例化对象 13.3.2如何给成员变量赋值 13.3.3如何调用成员函数 13.4何时使用反射 13.5动态异常处理框架 13.5.1框架功能简介 13.5.2重要技术 13.5.3框架代码编写 13.5.4使用该框架 13.6小结 第14章实验指导3 14.1字符频率统计软件 14.1.1软件功能简介 14.1.2重要技术 14.1.3项目结构 14.1.4代码编写 14.1.5思考题 14.2文本翻译软件 14.2.1软件功能简介 14.2.2重要技术 14.2.3项目结构 14.2.4代码编写 14.2.5思考题 14.3用享元模式优化程序性能 14.3.1为什么需要享元模式 14.3.2重要技术 14.3.3代码编写 14.3.4思考题 下篇UML 第15章UML入门 15.1认识UML 15.1.1为什么需要UML 15.1.2UML的来历 15.2用Rational Rose进行UML建模 15.2.1什么是Rational Rose 15.2.2安装Rational Rose 15.2.3如何使用Rational Rose 15.2.4UML图的种类 15.3小结 第16章用例图 16.1认识用例图 16.1.1为什么需要用例图 16.1.2什么是用例图 16.2详解用例图 16.2.1系统边界 16.2.2参与者 16.2.3用例 16.2.4箭头 16.2.5注释 16.2.6用Rational Rose画用例图 16.2.7用例规约 16.3一个案例 16.3.1案例描述 16.3.2画出用例图 16.3.3写出用例描述 16.4小结 第17章类图和对象图 17.1认识类图 17.1.1为什么需要类图 17.1.2什么是类图 17.2详解类图 17.2.1类 17.2.2箭头 17.2.3注释 17.2.4用Rational Rose画类图 17.3对象图 17.4小结 第18章实验指导4 18.1用例图练习 18.1.1软件功能简介 18.1.2识别系统中的参与者和用例 18.1.3画出用例图 18.1.4用例描述 18.2类图练习 18.2.1练习1: 根据代码画出类图 18.2.2练习2: 根据需求构建类图 18.3思考题 第19章顺序图、协作图、状态图和活动图 19.1顺序图 19.1.1什么是顺序图 19.1.2详解顺序图 19.1.3用Rational Rose画顺序图 19.2协作图 19.2.1什么是协作图 19.2.2详解协作图 19.2.3用Rational Rose画协作图 19.3状态图 19.3.1什么是状态图 19.3.2详解状态图 19.3.3用Rational Rose画状态图 19.4活动图 19.4.1什么是活动图 19.4.2详解活动图 19.4.3用Rational Rose画活动图 19.5小结 第20章包图、构件图和部署图 20.1包图 20.1.1什么是包图 20.1.2详解包图 20.1.3用Rational Rose画包图 20.2构件图 20.2.1什么是构件图 20.2.2详解构件图 20.2.3用Rational Rose画构件图 20.3部署图 20.3.1什么是部署图 20.3.2详解部署图 20.3.3用Rational Rose画部署图 20.4小结 第21章实验指导5 21.1顺序图、协作图练习 21.1.1功能简介 21.1.2创建顺序图 21.1.3创建协作图 21.2状态图、活动图练习 21.2.1功能简介 21.2.2创建状态图 21.2.3创建活动图 21.3包图、构件图和部署图练习
1.1 Java语言发展简史2 1.2 认识Java语言3 1.2.1 Java语言特性3 1.2.2 JavaApplet4 1.2.3 丰富的类库4 1.2.4 Java的竞争对手5 1.2.5 Java在应用领域的优势7 1.3 Java平台的体系结构7 1.3.1 JavaSE标准版8 1.3.2 JavaEE企业版10 1.3.3 JavaME微型版11 1.4 JavaSE环境安装和配置12 1.4.1 什么是JDK12 1.4.2 JDK安装目录和实用命令工具介绍12 1.4.3 设置环境变量13 1.4.4 验证配置的正确性14 1.5 MyEcilpse工具介绍JavaSE环境安装和配置15 1.6 本章练习16 第2章 2.1 什么是程序18 2.2 计算机中的程序18 2.3 Java程序19 2.3.1 Java程序中的类型19 2.3.2 Java程序开发三步曲21 2.3.3 开发Java第一个程序21 2.3.4 Java代码中的注释23 2.3.5 常见错误解析24 2.4 Java类库组织结构和文档27 2.5 Java虚拟机简介28 2.6 Java技术两种核心运行机制29 2.7 上机练习30 第3章 3.1 变量32 3.1.1 什么是变量32 3.1.2 为什么需要变量32 3.1.3 变量的声明和赋值33 3.1.4 变量应用实例33 3.2 数据的分类34 3.2.1 Java中的八种基本数据类型34 3.2.2 普及二进制36 3.2.3 进制间转换37 3.2.4 基本数据类型间转换38 3.2.5 数据类型应用实例38 3.2.6 引用数据类型39 3.3 关键字.标识符.常量39 3.3.1 变量命名规范39 3.3.2 经验之谈-常见错误的分析与处理40 3.3.3 Java标识符命名规则41 3.3.4 关键字42 3.3.5 常量42 3.4 运算符43 3.4.1 算术运算符43 3.4.2 赋值操作符45 3.4.3 关系操作符47 3.4.4 逻辑操作符48 3.4.5 位操作符49 3.4.6 移位运算符49 3.4.7 其他操作符50 3.5 表达式52 3.5.1 表达式简介52 3.5.2 表达式的类型和值52 3.5.3 表达式的运算顺序52 3.5.4 优先级和结合性问题52 3.6 选择结构54 3.6.1 顺序语句54 3.6.2 选择条件语句54 3.6.3 switch结构59 3.6.4 经验之谈-常见错误的分析与处理65 3.6.5 Switch和多重if结构比较66 3.7 循环语句66 3.7.1 While循环67 3.7.2 经验之谈-常见while错误70 3.7.3 do-while循环72 3.7.4 for循环74 3.7.5 经验之谈-for常见错误76 3.7.6 循环语句小结78 3.7.7 break语句79 3.7.8 continue语句82 3.8 JavaDebug技术84 3.9 本章练习85 第4章 4.1 一维数组90 4.1.1 为什么要使用数组90 4.1.2 什么是数组91 4.1.3 如何使用数组92 4.1.4 经验之谈-数组常见错误97 4.2 常用算法98 4.2.1 平均值,最大值,最小值98 4.2.3 数组排序102 4.2.3 数组复制103 4.3 多维数组105 4.3.1 二重循环105 4.3.2 控制流程进阶107 4.3.3 二维数组111 4.4 经典算法113 4.4.1 算法-冒泡排序113 4.4.2 插入排序115 4.5 增强for循环116 4.6 本章练习117 第5章 5.1 面向过程的设计思想120 5.2 面向对象的设计思想120 5.3 抽象121 5.3.1 对象的理解121 5.3.2 Java抽象思想的实现122 5.4 封装124 5.4.1 对象封装的概念理解124 5.4.2 类的理解125 5.4.3 Java类模板创建125 5.4.4 Java中对象创建和使用127 5.5 属性130 5.5.1 属性的定义130 5.5.2 变量131 5.6 方法132 5.6.1 方法的定义132 5.6.2 构造方法135 5.6.4 方法重载138 5.6.5 自定义方法138 5.6.6 系统提供方法139 5.6.7 方法调用140 5.6.8 方法参数及其传递问题144 5.6.9 理解main方法语法及命令行参数147 5.6.1 0递归算法147 5.7 this关键字148 5.8 JavaBean149 5.9 包150 5.9.1 为什么需要包?150 5.9.2 如何创建包151 5.9.3 编译并生成包:151
### 回答1: `String` 和 `StringBuffer` 在 Java 中是两种不同的字符串类型,它们的主要区别如下: 1. 可变性:`String` 类型是不可变的,一旦创建就不能更改,而 `StringBuffer` 类型是可变的,可以随时更改。 2. 效率:因为 `String` 类型是不可变的,所以在进行字符串拼接等操作时,每次操作都会创建一个新的字符串对象,因此效率较低。相反,`StringBuffer` 类型在进行操作时,会在内部维护一个可变的字符数组,因此效率较高。 3. 线程安全:`StringBuffer` 类型是线程安全的,可以在多线程环境中使用,而 `String` 类型不是线程安全的,不适合在多线程环境中使用。 因此,如果需要频繁修改字符串,或在多线程环境中使用字符串,则应使用 `StringBuffer`;否则,可以使用 `String`。 ### 回答2: stringstringbuffer都是java中用来表示字符串的类。它们之间的主要区别在于字符串的可变性和线程安全性。 首先,string是不可变的对象,一旦创建就不能被修改。这意味着每次对string进行修改都会创建一个新的string对象,而原始的string对象保持不变。这种设计确保了string对象在多线程环境下的安全性,但也会导致频繁创建新的对象,影响性能。 相比之下,stringbuffer是可变对象,可以进行插入、删除和修改等操作而不会创建新的对象。这能够提供更高的效率,尤其是需要频繁修改字符串的情况下。另外,stringbuffer还提供了多线程访问的安全性,因为它的操作方法都是同步的。 由于stringbuffer的线程安全性,它的性能相对较差,特别是在单线程环境下。为了提高性能,java还提供了stringbuilder类,它与stringbuffer相似,但不具备线程安全性。这使得stringbuilder在单线程环境下比stringbuffer更快,但在多线程环境下可能存在问题。 总的来说,string适用于不需要频繁修改字符串的场景,而stringbuffer适用于需要频繁修改字符串并且要求线程安全的场景。在单线程环境下,可以使用stringbuilder来提高性能。 ### 回答3: String是Java中的不可变类,即一旦创建,它的值就不可改变。而StringBuffer是可变类,可以进行插入、删除、替换等操作。 区别如下: 1. 内存使用:String每次字符串操作(如拼接)都会创建一个新的字符串对象,原字符串对象不变,需要消耗更多的内存空间。而StringBuffer则是对同一对象进行操作,节省内存空间。 2. 线程安全性:String是线程安全的,因为它是不可变的,多个线程可以同时访问同一个String对象而不会导致数据不一致。而StringBuffer是可变类,线程不安全,在多线程环境下需要进行同步处理,否则可能导致数据错误。 3. 性能:由于String是不可变的,每次对原字符串进行操作都会创建一个新的对象,生成大量垃圾对象,对性能有一定的影响。而StringBuffer是可变的,对原字符串进行操作不会生成新的对象,所以性能较高。 4. 方法和功能:String类提供了较多的操作字符串的方法,如substring()、concat()等。而StringBuffer除了提供与String类相同的方法外,还提供了很多用于插入、删除、替换字符串的方法,如append()、insert()、delete()等。 综上所述,String适用于字符串不经常改变的场景,如字符串常量等;而StringBuffer适用于频繁修改字符串的场景,如字符串拼接、修改等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值