`
sam406
  • 浏览: 57799 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

java基础之字符串

 
阅读更多
String 这玩意,对于Javer 来说,在面试或笔试是总让你魂牵梦绕哦。什么是否相等哦,什么这个字符串的结果是多少哦,有时候很厌恶这类型的题哈,如果你现在感到厌恶,就说明你还是没有弄明白这玩意的特性以及功能了,好吧。我就来说说这玩意的特点(以面试的方式)。
先看个例子
 String str1="abc";
  String str2="abc";
  String  str3=new String("abc");
  String str4=new String("abc");
   1) str1==str2  true;
   2) str1==str3   false
   3) str3==str4   false;

  说到1)比较就要牵扯到,常量池的知识咯。
   
我们都知道,Java程序要运行,首先需要编译器将源代码文件编译成字节码文件(也就是.class文件)。然后在由JVM解释执行,在class文件中有一个非常重要的项-就是常量池,它可以存放静态数据,常量,还有就是直接通过赋值创建的字符串,,在Java源代码中的每一个字面值字符串,都会在编译成class文件阶段,形成标志号 为8(CONSTANT_String_info)的常量表 。 当JVM加载 class文件的时候,会为对应的常量池建立一个内存数据结构,并存放在方法区中。同时JVM会自动为CONSTANT_String_info常量表中 的字符串常量字面值 在堆中 创建 新的String对象(intern字符串 对象 ,又叫拘留字符串对象)。然后把CONSTANT_String_info常量表的入口地址转变成这个堆中String对象的直接地址(常量池解 析)。  这里很关键的就是这个拘留字符串对象 。源代码中所有相同字面值的字符串常量只可能建立唯一一个拘留字符串对象。 实际上JVM是通过一个记录了拘留字符串引用的内部数据结构来维持这一特性的。在Java程序中,可以调用String的intern()方法来使得一个常规字符串对象成为拘留字符串对象。我们会在后面介绍这个方法的。

  所以str1和str2在常量池中都是指向了同一个地址,所以比较的结果是相等的咯
  str3和str4是创建了两个String 对象,所以str3和str4的地址是不一样的,所以他俩就不相等咯。
  再看例子
 String str="a";
    String str1="bc"
   String str2=st+st1;
   String str3="abc";
   str2==str3 false;
  

  这俩为啥不等咯,主要是这“+”的运算功效,当执行st+st1时,JVM首先会在堆中创建一个StringBuilder类,同时用st指向的拘留字符串对象完成初始化,然后调用append方法完成对st1所指向的拘留字符串的合并操作,接着调用StringBuilder的toString()方法在堆中创建一个String对象,最后将刚生成的String对象的堆地址存放在局部变量st2中。而局部变量str3存储的是常量池中"abc"所对应的拘留字符串对象的地址。 st2与st3地址当然不一样了。这里要注意了,堆中实际上有五个字符串对象:三个拘留字符串对象、一个String对象和一个StringBuilder对象。
String sc="ab"+"cd";  
String sd="abcd";  
System.out.println(sc==sd); //true 

"ab"+"cd"会直接在编译期就合并成常量"abcd", 因此相同字面值常量"abcd"所对应的是同一个拘留字符串对象,所以地址是相同的咯。
 
 




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics