String和StringBuffer的一点研究
转载自:http://www.cnblogs.com/heshan664754022/archive/2013/03/15/2961463.html
首先请看下下面的这几个输出的结果,请仔细考虑,不要那么快回答!
String new String( "aaa" ); String new String( "aaa" ); System.out.println(str System.out.println( "----------------" ); String "bbb" ; String "bbb" ; System.out.println(str3 System.out.println( "----------------" ); String new String( "ccc" ); String "ccc" ; System.out.println(str5 System.out.println( "----------------" ); String "hello" ; String "hel" ; String "lo" ; System.out.println(s System.out.println( "----------------" ); System.out.println(s "hel" + "lo" ); |
到了这里相信你已经做出了答案,正确的结果是:
false true false false true
下面让我们来仔细的分析下,首先是第一个
String new String( "aaa" ); String new String( "aaa" ); System.out.println(str |
在看这道题的时候希望大家先看下下面这段原理性的描述
String s = new String(“aaa”);
1) 首先在String Pool中查找有没有“aaa”这个字符串对象,如果有,则不在String Pool中再去创建“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中创建的这个“aaa”字符串对象。
2) 如果没有,则首先在String Pool中创建一个“aaa“对象,然后再在堆中(heap)创建一个”aaa“对象,然后将堆中的这个”aaa“对象的地址返回来,赋给s引用,导致s指向了堆中所创建的这个”aaa“对象。
看完上面这段描述,相信大家应该明白了吧 str和str2引用分别指向了堆中的不同对象,所以地址不同,结果当然为false
然后第二个
String "bbb" ; String "bbb" ; System.out.println(str3 |
在此之前我们同样也先看一段原理性的描述:
String str3 = “bbb”;(采用字面值方式赋值)
1) 查找String Pool中是否存在“bbb”这个对象,如果不存在,则在String Pool中创建一个“bbb”对象,然后将String Pool中的这个“bbb”对象的地址返回来,赋给引用变量str3 ,这样str3 会指向StringPool中的这个“bbb”字符串对象
2) 如果存在,则不创建任何对象,直接将String Pool中的这个“bbb”对象地址返回来,赋给str3 引用。
看完之后相信也不用我多说了吧,str3和str4引用指向了同一个对象地址,结果当然是true
然后是第三个,相信如果你明白了前两个的话第三个就不用我多说什么了,如果不明白请先明白前两个。
现在我们来看第四个
String "hello" ; String "hel" ; String "lo" ; System.out.println(s |
在看这个问题时我们同样看一下一段原理性的描述:
String是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的String对象,而不是向原有的String对象追加内容。
所以当s1+s2时其实是在堆里面重新创建了一个新的对象,所以s与s1+s2的地址是不一样的。
对于最后一个问题
System.out.println(s == "hel" + "lo");
我的理解是JVM对于字符串常量的"+"号连接,将程序编译期,
JVM就将常量字符串的"+"连接优化为连接后的值,拿"hel" + ”lo“来说,经编译器优化后在class中就已经是hello。
在编译期其字符串常量的值就确定下来,存放在字符串常 量池中,故上面程序最终的结果都为true。
下面附加一个Stringbuffer的题目:
StringBuffer new StringBuffer( "hello" ); StringBuffer new StringBuffer( "hello" ); System.out.println(sb1.equals(sb2)); |
不要回答是true哦,在StringBuffer里面没有重写equals方法,所以使用的是Object的equals方法,所以它们比较的是地址,结果当然是false了。
总结:如果你能搞明白上面几个问题,相信你对String类有了一个更深的认识了,下面我们来总结一下:
栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容
堆中存放使用new关键字创建的对象.
字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常量池中,而有的是运行时才被创建.使用new关键字,存放在堆中,我们要根据情况来判断,其实要是理解了原理一切类似的问题就迎刃而解。
String和StringBuffer的一点研究的更多相关文章
- 浅析String、StringBuffer、StringBuilder的区别以及性能区别
前奏: 比较三者之间的区别在与区别他们做相同的事情的时候的区别,那就是在我们常见的拼接字符串的时候,StringBuffer.StringBuilder调用的是appende()方法,而String很 ...
- String、StringBuffer与StringBuilder之间区别
关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.三者在执行速度方面的比较:StringBuilder > String ...
- (转)String、StringBuffer与StringBuilder之间区别
原文地址: http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺 ...
- String、Stringbuffer、StringBuilder的区别(转载)
最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...
- String、StringBuffer和StringBuilder的深入解析
今天闲来无事,整理了下平时记录在印象笔记里的java开发知识点,整理到String,StringBuffer以及StringBuilder的区别时突然又产生了新的疑惑,这些区别是怎么产生的?温故为何能 ...
- String、StringBuffer与StringBuilder之间区别[全屏看文]
String.StringBuffer与StringBuilder之间区别[全屏看文] 最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,S ...
- 新手容易混乱的String+和StringBuffer,以及Java的方法参数传递方式。
之前在交流群里和猿友们讨论string+和stringbuffer哪个速度快以及Java的方法参数传递的问题,引起了群里猿友的小讨论.最终LZ得出的结果是string+没有stringbuffer快, ...
- JAVA中String与StringBuffer的区别
String和StringBuffer的区别,网上资料可以说是数不胜数,但是看到这篇文章,感觉里面做的小例子很有代表性,所以转一下,并自己做了一点总结. 在java中有3个类来负责字符的操作. 1.C ...
- 【转载】String、StringBuffer与StringBuilder之间区别
文章来源:http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 这两天在看Java编程的书,看到String的时候将之前没有弄懂的 ...
随机推荐
- 【备忘】mysql常用操作汇总
1.增删改查 // 插入一条数据 insert into tableName values('liu','bei') // 删除一条数据 delete from tableName where las ...
- cp的使用
一.形式 cp [options] source1 source2 source3 .... directory 参数意义: 参数 意义 -i 当目标文件已存在时,会询问是否覆盖 -p 连同文件的属性 ...
- Thunder团队第五周 - Scrum会议7
Scrum会议7 小组名称:Thunder 项目名称:i阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...
- Thunder团队第三周 - Scrum会议5
Scrum会议5 小组名称:Thunder 项目名称:i阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...
- Git 命令基本应用
两种建立仓库的方法: (1)在本地文件路径下建立仓库:git init (2)在代码托管网站上克隆项目:git clone [url] 查看该分支下的文件情况:git status 添加远程仓库源:g ...
- java---Map接口实现类
Map是一个双列集合接口,如果实现了Map接口,特点是数据以键值对形式存在,键不可重复,值可以重复.java中主要有HashMap.TreeMap.Hashtable.本文主要介绍Map的接口方法: ...
- 内部网关协议RIP 路由选择算法(距离向量)
RIP是一种基于距离向量的路由选择协议 RIP的距离就是指的跳数,没经过一个路由,就是一跳,RIP允许一跳路径最多经过15个路由器,所以16个的话就相当于不可以到达了 RIP协议的特点: 1:仅和相邻 ...
- iOS开发开辟线程总结--NSThread
1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...
- 微信小程序wx.pageScrollTo的替代方案
wx.pageScrollTo这个微信小程序的api功能如下: 简而言之就是实现页面滚动的.但是在实际应用当中显得有些鸡肋,为啥呢?使用中有明显页面有明显的抖动,这无疑是极不好的用户体验.我用的华为6 ...
- java 基础 --int 和Integer的区别
感到脸红:int是整形 -128~127 Integer是正整型,你怎么会想到这样的回答,妈的,有脑子吗?!!! 1,int是基本数据类型,初始为0,Integer为封装类,初始为null ①无论如何 ...