转载自:http://www.cnblogs.com/heshan664754022/archive/2013/03/15/2961463.html

首先请看下下面的这几个输出的结果,请仔细考虑,不要那么快回答!

String
str =
new String("aaa");
 
String
str2 =
new String("aaa");
 
System.out.println(str
== str2);
 
System.out.println("----------------");
 
String
str3 =
"bbb";
 
String
str4 =
"bbb";
 
System.out.println(str3
== str4);
 
  
 
System.out.println("----------------");
 
String
str5 =
new String("ccc");
 
String
str6 =
"ccc";
 
System.out.println(str5
== str6);
 
System.out.println("----------------");
 
String
s =
"hello";
 
String
s1 =
"hel";
 
String
s2 =
"lo";
 
System.out.println(s
== s1 + s2);
 
System.out.println("----------------");
 
System.out.println(s
==
"hel" +
"lo");

到了这里相信你已经做出了答案,正确的结果是:

false   true  false  false    true

下面让我们来仔细的分析下,首先是第一个

String
str =
new String("aaa");
 
String
str2 =
new String("aaa");
 
System.out.println(str
== str2);

  

在看这道题的时候希望大家先看下下面这段原理性的描述

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
str3 =
"bbb";
 
String
str4 =
"bbb";
 
System.out.println(str3
== str4);

在此之前我们同样也先看一段原理性的描述:

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
s =
"hello";
 
String
s1 =
"hel";
 
String
s2 =
"lo";
 
System.out.println(s
== s1 + s2);

在看这个问题时我们同样看一下一段原理性的描述:

String是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的String对象,而不是向原有的String对象追加内容。

所以当s1+s2时其实是在堆里面重新创建了一个新的对象,所以s与s1+s2的地址是不一样的。

对于最后一个问题

System.out.println(s == "hel" + "lo");

我的理解是JVM对于字符串常量的"+"号连接,将程序编译期,

JVM就将常量字符串的"+"连接优化为连接后的值,拿"hel" + ”lo“来说,经编译器优化后在class中就已经是hello。

在编译期其字符串常量的值就确定下来,存放在字符串常 量池中,故上面程序最终的结果都为true。

下面附加一个Stringbuffer的题目:

StringBuffer
sb1 =
new StringBuffer("hello"); 
StringBuffer
sb2 =
new StringBuffer("hello");
System.out.println(sb1.equals(sb2));
不要回答是true哦,在StringBuffer里面没有重写equals方法,所以使用的是Object的equals方法,所以它们比较的是地址,结果当然是false了。

总结:如果你能搞明白上面几个问题,相信你对String类有了一个更深的认识了,下面我们来总结一下:

栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容

堆中存放使用new关键字创建的对象.

字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常量池中,而有的是运行时才被创建.使用new关键字,存放在堆中,我们要根据情况来判断,其实要是理解了原理一切类似的问题就迎刃而解。

String和StringBuffer的一点研究的更多相关文章

  1. 浅析String、StringBuffer、StringBuilder的区别以及性能区别

    前奏: 比较三者之间的区别在与区别他们做相同的事情的时候的区别,那就是在我们常见的拼接字符串的时候,StringBuffer.StringBuilder调用的是appende()方法,而String很 ...

  2. String、StringBuffer与StringBuilder之间区别

    关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.三者在执行速度方面的比较:StringBuilder >  String ...

  3. (转)String、StringBuffer与StringBuilder之间区别

    原文地址: http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺 ...

  4. String、Stringbuffer、StringBuilder的区别(转载)

    最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...

  5. String、StringBuffer和StringBuilder的深入解析

    今天闲来无事,整理了下平时记录在印象笔记里的java开发知识点,整理到String,StringBuffer以及StringBuilder的区别时突然又产生了新的疑惑,这些区别是怎么产生的?温故为何能 ...

  6. String、StringBuffer与StringBuilder之间区别[全屏看文]

    String.StringBuffer与StringBuilder之间区别[全屏看文]   最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,S ...

  7. 新手容易混乱的String+和StringBuffer,以及Java的方法参数传递方式。

    之前在交流群里和猿友们讨论string+和stringbuffer哪个速度快以及Java的方法参数传递的问题,引起了群里猿友的小讨论.最终LZ得出的结果是string+没有stringbuffer快, ...

  8. JAVA中String与StringBuffer的区别

    String和StringBuffer的区别,网上资料可以说是数不胜数,但是看到这篇文章,感觉里面做的小例子很有代表性,所以转一下,并自己做了一点总结. 在java中有3个类来负责字符的操作. 1.C ...

  9. 【转载】String、StringBuffer与StringBuilder之间区别

    文章来源:http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 这两天在看Java编程的书,看到String的时候将之前没有弄懂的 ...

随机推荐

  1. 【Paper】Deep & Cross Network for Ad Click Predictions

    目录 背景 相关工作 主要贡献 核心思想 Embedding和Stacking层 交叉网络(Cross Network) 深度网络(Deep Network) 组合层(Combination Laye ...

  2. 官方文档 恢复备份指南一 Introduction to Backup and Recovery

    1.备份分为:物理备份和逻辑备份    物理备份:备份数据文件  控制文件  归档日志文件     逻辑备份:EXP EXPDP备份等 物理备份为主,逻辑做补充     2.错误的类型         ...

  3. Twaver的mono-desiner导出的json文件解析

    以画的交换机为例,其他大概都差不多. 利用Twaver做出交换机模型如图1所示,其中,每一个端口都是一个单独的对象.具体Twaver操作流程参见网址:http://twaver.servasoft.c ...

  4. c# byte[] 保存图片

    1.用函数即可,File.WriteAllBytes(@"E:\123.bmp", pcBMPBuffer); 2.byte[]也可和image互相转化.

  5. Uva 1600 Patrol Robot (BFS 最短路)

    这道题运用的知识点是求最短路的算法.一种方法是利用BFS来求最短路. 需要注意的是,我们要用一个三维数组来表示此状态是否访问过,而不是三维数组.因为相同的坐标可以通过不同的穿墙方式到达. #inclu ...

  6. 我爱C语言

    各位同志们好,我是来自计算机系的谢畅,我是一个平时看起来高冷其实很逗比的人,我的爱好有很多但只是会一些基础比如游泳,篮球,听听音乐什么的.我的特长是弹吉他虽然弹得不是很溜,我还喜欢朗诵.刚开始我并不是 ...

  7. deep learning2

    九.Deep learning的常用模型或者方法 9.1.AutoEncoder自动编码器 Deep Learning最简单的一种方法是利用人工神经网络的特点,人工神经网络(ANN)本身就是具有层次结 ...

  8. RT-thread内核之小内存管理算法

     一.动态内存管理 动态内存管理是一个真实的堆(Heap)内存管理模块,可以在当前资源满足的情况下,根据用户的需求分配任意大小的内存块.而当用户不需要再使用这些内存块时,又可以释放回堆中供其他应用分配 ...

  9. BZOJ 1787 紧急集合(LCA)

    转换成抽象模型,就是要求一棵树(N个点,有N-1条边表示这个图是棵树)中某一点满足给定三点a,b,c到某一点的距离和最小.那么我们想到最近公共祖先的定义,推出只有集合点在LCA(a,b).LCA(a, ...

  10. Python面向对象—类的继承

    一个子类可以继承父类的所有属性,不管是父类的数据属性还是方法. class Father(object): num = 0 def __init__(self): print "I'm Pa ...