java里的String Pool

来源:互联网 发布:ubuntu防火墙关闭 编辑:程序博客网 时间:2024/04/30 02:29

String="abc"是存放在栈里的,准确说应该是存放在String Pool里的,跟原始型变量是一样的

String s=new String("abc")是存放在堆里的,跟对象是一样的



其实只要理解以下知识:

    String 是存放在java栈中,当创建一个String对象时(其他存放在栈中的基本类型变量类似),会去栈中查找是否有相同值的String,如果有则将变量地址赋给变量引用,没有则创建一个变量,同时将地址赋给引用。以上不适用于new 申明的变量;

因为new 关键字创建的变量都是存储与堆中的。


以下是转载文章:


在jvm中存在着String Pool
  String对象是不变对象,在程序运行过程中可能用到多个具有相同值得String对象,jvm中使用String pool来优化这种情况。当有新的String对象要建立的时候,jvm先检查Pool中时候已经有具有相同值的String对象,如果有就把这个对象的引用传递给新建立的对象,如果没有,就新建立一个对象,并将它放到Pool中。
  String对象的建立有两种方式:
  String s = "abc";
  or
  String s = new String("abc");
  在String Pool中这两种方式建立的对象有所不同,实际上String Pool只是对无名称String对象有效,即:通过方式一建立的具有相同值的对象也具有相同的内存地址。而对于通过new来建立的对象并不起作用,即用这样方式建立的对象具有自己的内存空间。
class hello{
  public static void main(String args[]){
  String s1 = "abc";
  String s2 = "abc";
  System.out.println("s1==s2? "+(s1==s2));
  System.out.println("s1.equal(s2)? "+s1.equals(s2));
  String s3 = new String("abc");
  String s4 = new String("abc");
  System.out.println("s3==s4? "+(s3==s4));
  System.out.println("s3.equal(s4)? "+s3.equals(s4));
  System.out.println("s1==s3? "+(s1==s3));
  System.out.println("s1.equal(s3)? "+s1.equals(s3));
  }
  }

结果:
  s1==s2? true //-- ps: s1和s2具有相同的内存地址。
  s1.equal(s2)? true
  s3==s4? false //-- ps: s3和s4具有不同内存地址。
  s3.equal(s4)? true
  s1==s3? false
  s1.equal(s3)? true
  下面的代码会输出什么呢? :)
  class hello{
  public static void main(String args[]){
  String s5 = new String("abc");
  String s6 = "abc";
  System.out.println("s5==s6? "+(s5==s6));
  System.out.println("s5.equal(s6)? "+s5.equals(s6));
  }
  }
  结果:
  s5==s6? false
  s5.equal(s6)? true
  预料之中!

以上这句说话并没有错.那是在说String 放在String pool时的特例.
  for example:
  String a = "abc"; // 检查String pool有没有这组字串,发现没有就create一个
  String b = "abc"; // 检查String pool有没有这组字串,发现有,就直接引用它的reference
  if(a==b) 是true;
  但当用到new时就会有如下的情形.
  String a = new String("abc"); 
  // 检查String pool有没有这组字串,发现没有就create一个,
  // 因为用new,所以同时亦建立一个新的instance给它.
  String b = new String("abc"); 
  // 检查String pool有没有这组字串,发现有,就直接引用它的reference
  // 因为用new,所以同时亦建立另一个新的instance给它.
  知道为甚麽new String("abc")亦要检查String pool吗.
  那是因为String()的constructor是原因.
  这是其中一个String的constructor : String(String original).
  留意当new String("abc")时.
  其实已经先做了一个动作,String original = "abc".


        static String str ="HelloWorld";

public static void main(String[] args) {
String A = "Hello";
String B = "World";
String C = "Hello"+"World";


System.out.println((A+B)==str);
System.out.println(C==str);
}
结果是:false,true

Java 语言提供对字符串串联符号("+")。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。

String+是StringBuffer的append()方法来实现的,如: 
String   str   =   new   String( "abc "); 
编译时等效于 
String   str   =   new   StringBuffer().append( "a ").append( "b ").append( "c ").toString();

A+B //  会产生一个新的引用,System.out.println((A+B)==str);返回false

补充2011.06.24:

字符串对象的创建:由于字符串对象的大量使用[它是一个对象,一般而言对象总是在heap分配内存],Java中为了节省内存空间和运行时间[如比较字符串时,==比equals()快],在编译阶段就把所有的字符串文字放到一个文字池[pool of literal strings]中,而运行时文字池成为常量池的一部分。文字池的好处,就是该池中所有相同的字符串常量被合并,只占用一个空间。我们知道,对两个引用变量,使用==判断它们的值[引用]是否相等,即指向同一个对象:

String s1 = new String("abc") ;String s2 = new String("abc") ;if( s1 == s2 ){ //不会执行的语句}

    这时用==判断就可知,虽然两个对象的"内容"相同[equals()判断],但两个引用变量所持有的引用不同,

    BTW:上面的代码创建了几个String Object? [三个,pool中一个,heap中2个。]

0 0
原创粉丝点击