最近被问到string的一些基础知识,居然不会,上网看了一些文章总结一下加深理解。<o:p></o:p>
String既可以作为一个对象来使用,又可以作为一个基本类型来使用。导致String类比较特殊,容易混淆。这里指的作为一个基本类型来使用只是指使用方法上的。<o:p></o:p>
比如String s= "Hello",它的使用方法如同基本类型int一样,如int i=1;,<o:p></o:p>
而作为一个对象来使用,则是指通过new关键字来创建一个新对象,如<o:p></o:p>
String s = new String("Hello")。<o:p></o:p>
<o:p> </o:p>
一.作为对象使用<o:p></o:p>
String s1 = new String("Hello");
String s2 = new String("Hello");<o:p></o:p>
String s3 =s2;<o:p></o:p>
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));<o:p></o:p>
System.out.println(s2 == s3);
System.out.println(s2.equals(s3));<o:p></o:p>
以上代码段的打印结果是:<o:p></o:p>
false
true
true
true
结果很好理解<o:p></o:p>
"=="来比较它们所引用的是否是同一个对象时,<o:p></o:p>
equals()方法来比较所封装的字符串内容是否完全相同。<o:p></o:p>
总结:
如String作为一个对象来使用,那么虚拟机将为此创建一个新的String对象,即为此对象分配一块新的内存堆,并且它并不是String缓冲池所拥有的,即它是独立的。<o:p></o:p>
<o:p> </o:p>二.作为基本类型使用<o:p></o:p>
以上是标准的创建对象的动作,但是String对象还可以当作基本类型来使用,<o:p></o:p>
但是它的内部动作其实还是创建了一个对象,分配一块新的、独立的内存堆。<o:p></o:p>
如String s = "Hello";<o:p></o:p>
看到这里,对String对象还没搞清楚的朋友开始疑惑了,你肯定会问,这个使用方法在其内部到底发生了什么?这就是String对象容易混淆的关键!<o:p></o:p>
其实在启动程序时,虚拟机会创建一块String对象的String缓冲池。当String对象作为一个基本类型来使用时,比如:String s = "Hello";;,虚拟机会先在这个String缓冲池内寻找是否有相同值的String对象存在,如果存在,则把这个String对象的引用赋值给s。 如果不存在,虚拟机会先在这个String缓冲池内创建此String对象,然后把引用赋值给s。<o:p></o:p>
说到这里,相信大家已经开始明白了。那么请看下面的代码段:<o:p></o:p>
String s1 = "Hello";
String s2 = "Hello";<o:p></o:p>
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));<o:p></o:p>
以上代码段的打印结果是:<o:p></o:p>
true
true<o:p></o:p>
为什么这个结果?那么来分析一下。首先这两个String对象都是作为一个基本类型来使用的,而不是通过new关键字来创建的,因此虚拟机不会为这两个String对象分配新的内存堆,而是到String缓冲池中来寻找。<o:p></o:p>
首先为s1寻找String缓冲池内是否有与"Hello"相同值的String对象存在,此时String缓冲池内是空的,没有相同值的String对象存在,所以虚拟机会在String缓冲池内创建此String对象,其动作就是new String("Hello");。然后把此String对象的引用赋值给s1。<o:p></o:p>
接着为s2寻找String缓冲池内是否有与"Hello"相同值的String对象存在,此时虚拟机找到了一个与其相同值的String对象,这个String对象其实就是为s1所创建的String对象。既然找到了一个相同值的对象,那么虚拟机就不在为此创建一个新的String对象,而是直接把存在的String对象的引用赋值给s2。<o:p></o:p>
这里既然s1和s2所引用的是同一个String对象,即自己等于自己,所以以上两种比较方法都返回ture。<o:p></o:p>
总结
针对String作为一个基本类型来使用:<o:p></o:p>
1。如果String作为一个基本类型来使用,那么我们视此String对象是String缓冲池所拥有的。
2。如果String作为一个基本类型来使用,并且此时String缓冲池内不存在与其指定值相同的String对象,那么此时虚拟机将为此创建新的String对象,并存放在String缓冲池内。
3。如果String作为一个基本类型来使用,并且此时String缓冲池内存在与其指定值相同的String对象,那么此时虚拟机将不为此创建新的String对象,而直接返回已存在的String对象的引用。<o:p></o:p>
理解了以上内容后,请看以下代码段:<o:p></o:p>
String s1 = "Hello";
String s2 = new String("Hello"); <o:p></o:p>
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));<o:p></o:p>
以上代码段的打印结果是:<o:p></o:p>
false
true<o:p></o:p>
根据上面的小结来进行分析。第一行是把String作为一个基本类型来使用的,因此s1所引用的对象是属于String缓冲池内的。并且此时String缓冲池内并没有与其值相同的String对象存在,因此虚拟机会为此创建一个新的String对象,即new String("Hello");。第二行是把String作为一个对象来使用的,因此s2所引用的对象不属于String缓冲池内的,即它是独立的。通过new关键字,虚拟机会为此创建一个新的String对象,即为它分配了一块新的内存堆。因此"=="比较后的结果是false,因为s1和s2所引用的并不是同一个对象,它们是独立存在的。而equals()方法所返回的是true,因为这两个对象所封装的字符串内容是完全相同的。<o:p></o:p>
现在,相信大家已经完全搞清楚String对象是怎么一回事了:)但是到此并没有结束,因为String对象还有更深层次的应用。<o:p></o:p>
三.intern()方法<o:p></o:p>
这里我将分析一下String对象的intern()方法的应用。
intern()方法将返回一个字符串对象的规范表示法,即一个同该字符串内容相同的字符串,但是来自于唯一字符串的String缓冲池,这样将对重复的消息进行共享机制,从而降低了内存消耗,提高了性能。<o:p></o:p>
String s = new String("Hello");
s = s.intern();<o:p></o:p>
以上代码段的功能实现可以简单的看成如下代码段:<o:p></o:p>
String s = "Hello";<o:p></o:p>
你一定又开始疑惑了?那么你可以先看第二个代码段。第二个代码段的意思就是从String缓冲池内取出一个与其值相同的String对象的引用赋值给s。如果String缓冲池内没有与其相同值的String对象存在,则在其内为此创建一个新的String对象。那么第一段代码的意思又是什么呢?我们知道通过new关键字所创建出的对象,虚拟机会为它分配一块新的内存堆。如果平凡地创建相同内容的对象,虚拟机同样会为此分配许多新的内存堆,虽然它们的内容是完全相同的。拿String对象来说,如果连续创建10个相同内容的String对象(new String("Hello")),那么虚拟机将为此分配10块独立的内存堆。假设所创建的String对象的字符串内容十分大,假设一个Stirng对象封装了<st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="m">1M</st1:chmetcnv>大小的字符串内容,那么如果我们创建10个此相同String对象的话,我们将会毫无意义的浪费<st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="9" unitname="m">9M</st1:chmetcnv>的内存空间。我们知道String是final类,它所封装的是字符串常量,因此String对象在创建后其内部(字符串)值不能改变,也因此String对象可以被共享。所以对于刚才提到的假设,我们所创建的10个相同内容的String对象,其实我们只需为此创建一个String对象,然后被其它String变量所共享。要实现这种机制,唯一的、简单的方法就是使用String缓冲池,因为String缓冲池内不会存在相同内容的String对象。而intern()方法就是使用这种机制的途径。在一个已实例化的String对象上调用intern()方法后,虚拟机会在String缓冲池内寻找与此Stirng对象所封装的字符串内容相同值的String对象,然后把引用赋值给引用原来的那个String对象的String类型变量。如果String缓冲池内没有与此String对象所封装的字符串内容相同值的String对象存在,那么虚拟机会为此创建一个新的String对象,并把其引用赋值给引用原来的那个String对象的String类型变量。这样就达到了共享同一个String对象的目的,而原先那个通过new关键字所创建出的String对象将被抛弃并被垃圾回收器回收掉。这样不但降低了内存的使用消耗,提高了性能,而且在String对象的比较上也同样更方便了,因为相同的String对象将被共享,所以要判断两个String对象是否相同,则只需要使用"=="来比较,而无需再使用equals()方法来比较,这样不但使用起来更方便,而且也提高了性能,因为String对象的equals()方法将会对字符串内容拆解,然后逐个进行比较,如果字符串内容十分大的话,那么这个比较动作则大大降低了性能。
分享到:
相关推荐
这份"javaString总结共13页.pdf.zip"压缩包文件显然包含了关于Java字符串的深入讲解,覆盖了多个关键知识点。虽然没有提供具体的PDF内容,但我可以基于常见的Java String主题为你概述一些重要的概念。 1. **字符串...
title: STL中的vector string总结vector在C++编程中经常会被使用。初始化// 类似于数组的方式//使用构造函数的方式。
在任何编程语言中,字符串都是重中之重。通过使用XMind总结C++ XMind中的字符串,了解并熟练掌握string对象的构造和初始化,插入删除替换,查找和比较,把所有相关的操作整合在一个页面上,提高工作效率
### C++ `string` 类型的使用总结 在C++编程语言中,`string` 类是一种非常重要的数据结构,用于处理文本数据。本篇总结旨在详细介绍`string` 类的构造方法、常用操作方法及其功能特性。 #### 一、`string` 类对象...
1 split字符串 之前在用C#写代码的时候,用过split函数,可以把一个字符串根据...string inputString(/home/fun/./../code/); stringstream ss(inputString); string tmp; while(getline(ss,tmp,'/')) { if(tmp.empty
### 标准C++中的`string`类的用法总结 在C++编程语言中,`string`类是处理字符串的利器,它提供了丰富的功能,远远超过了传统的C风格字符串(即`char*`)。`string`类封装了字符串操作的所有细节,使得字符串处理变...
#### 总结 - **使用场景**: - 当需要频繁地对字符串进行修改操作时(如字符串拼接),推荐使用 `StringBuffer`,因为它能够提供更好的性能。 - 如果只需要读取字符串且不打算对其进行修改,则使用 `String` 更为...
#### 六、总结 本文详细介绍了C#中字符串与其他数据类型之间的转换方法,包括但不限于整数、浮点数、十六进制及二进制。通过这些方法,开发者可以更加灵活地处理不同数据类型之间的转换需求。此外,还特别强调了...
标题:“String类方法总结” 描述:“string类方法总结,由毕姥爷精心提炼,被誉为学习String类的必读经典。” **知识点详述:** 在Java编程语言中,`String`类是一个极其重要的类,用于处理文本数据。由于其不可...
总结一下,C#中的`string`和`String`虽然在日常使用中差异不大,但理解它们的本质区别对于编写高效的代码至关重要。同时,掌握字符串比较、格式化和正则表达式的使用也是提升C#编程能力的关键点。希望这些知识点能对...
#### 四、总结 通过以上四种方法,我们可以轻松地将`List<String>`转换为`String[]`。每种方法都有其适用场景和特点,选择哪种取决于具体的应用需求和个人偏好。对于大多数情况而言,建议使用第一种或第二种方法,...
总结来说,`String`(或`string`)在C#中是文本数据的主要载体,其不可变特性确保了代码的安全性和效率。在ASP.NET和SQL数据库操作中,`string`是构建动态查询和处理网络数据的关键元素。理解和熟练运用`string`类型...
总结,JavaBean和JsonString的转换是Java开发中的常见操作,通过各种JSON库可以轻松实现。了解这些转换方法对于进行前后端数据交互、序列化和反序列化等任务至关重要。在实际开发中,应根据项目需求选择合适的库,并...
### 标题解读:“String.split()方法使用总结” 标题明确指出本文将围绕`String.split()`方法的使用进行深入探讨,旨在总结其功能、用法以及一些实践中的注意事项。这表明文章的目标读者是对Java编程有一定了解,...
在Linux系统中,`string`函数是一组非常基础且实用的C语言库函数,它们主要用于处理字符串。在C语言编程中,字符串处理是常见的任务,包括比较、复制、连接、查找...在学习过程中,不断实践和总结,是提升技能的关键。
### JAVA String 类函数总结 #### 一、字符串创建与初始化 在 Java 中,`String` 类是最常用的字符串处理工具之一。它可以用来表示一系列字符,并且提供了丰富的方法来操作这些字符。下面通过示例代码展示了如何...
根据提供的信息,我们可以总结出这份Java基础String类选择题练习题主要聚焦于String及StringBuffer类的使用。尽管具体的题目内容未给出,但从所展示的信息中可以推断出该练习题集涵盖了以下几方面的知识点: ### 一...
总结起来,`std::string`是C++中处理字符串的重要工具,它提供了丰富的功能和便捷的API,使得字符串操作变得简单而高效。理解并熟练使用`std::string`,对提升编程能力大有裨益。在学习和实践中,我们应该不断探索其...