随笔-204  评论-149  文章-0  trackbacks-0

java.lang.String的intern()方法
"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作:
检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用。
我们做个测试:
      String str1 = "a";
String str2 = "bc";
String str3 = "a"+"bc";
String str4 = str1+str2;
  
System.out.println(str3==str4);
str4 = (str1+str2).intern();
System.out.println(str3==str4);
输出的结果将会是:
false
true
JDK的api文档是这么解释的:
=======================================================================
返回字符串对象的规范化表示形式。
一个初始时为空的字符串池,它由类 String 私有地维护。
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
所有字面值字符串和字符串赋值常量表达式都是内部的。字符串字面值在《Java Language Specification》的 §3.10.5 中已定义。

返回:
一个字符串,内容与此字符串相同,但它保证来自字符串池中。
=======================================================================

字符串字面池指的是常量池.

字符串对象的创建方式有两种

如下:

String s1 = new String("");   //第一种

String s2 = "";               //第二种

第一种始终不会入池的.

第二种要看情况而定(等号右边如果是常量则入池,非常量则不入池)

例:

String s3 = "a" + "b"; //"a"是常量,"b"是常量,常量+常量=常量,所以会入池.

String s4 = s1 + "b";   //s1是变量,"b"是常量,变量+常量!=常量,所以不会入池.
         //那引用s4所指的对象在哪里创建??????

一旦入池的话,就会先查找池中有无此对象.如果有此对象,则让对象引用指向此对象;如果无此对象,则先创建此对象,再让对象引用指向此对象.

例:

String s5 = "abc"; //先在池中查找有无"abc"对象,如果有,则让s5指向此对象;如果池中无"abc"对象,则在池中创建一个"abc"对象,然后让s5指向该对象.补充一下:

看了字节码后,发现
String str ="a"+"b";
完全等同于
String str="ab";


 -----------------------------------------------------------------------------------------------------------------------------

Java虚拟机有一个字符串池,保存着几乎所有的字符串常量。字符串表达式总是指向字符串池中的一个对象。
public class Test...{
 public static void main(String[] args)...{
  String s1=new String("abc");
  String s2="abc";//放入String池里
  String s3=new String("abc");
  System.out.println(s1==s2);//false
  System.out.println(s1==s3);//false
  System.out.println(s3==s2);//false
  System.out.println(s1==s1.intern());//s1.intern()到String池里找,而s1是在堆中所以返回false
  System.out.println(s2==s2.intern());//true
  System.out.println(s1.intern()==s3.intern());//两个字符串同时到String池里查找,返回true
 
   //以下三个都放到String池
  String hello="hello";
  String hel="hel";
  String lo="lo";
  System.out.println(hello=="hel"+"lo");//字符串相加以后,会到String池里找,有不产生,所以返回true
  System.out.println(hello=="hello");//直接到String池里找,返回true
  System.out.println(hello=="hel"+lo);//字符串加一个引用,将产生一个新的对象,所以返回false
  System.out.println(hello==(hel+lo));//类似上面,返回false
  System.out.println(hello==(hel+lo).intern());//产生新的对象,但是有intern()方法,将到String池中找,返回true
 }
}

 1package com._6617.fhs.weatherservice;
 2
 3import java.util.HashSet;
 4import java.util.Set;
 5
 6public class Test {
 7
 8    /**
 9     * @param args
10     */

11    public static void main(String[] args){
37        
38        Set set = new HashSet();
39        set.add(new A());
40        set.add(new A());
41        set.add(new A());
42        System.out.println(set.size());
                //主要是看类A是否自己实现了hashcode和equals方法
43        
44        String s = new String("abc");
45        System.out.println(s=="abc");//f
46        System.out.println(s=="a"+"bc");//f
47        String t ="abc";
48        System.out.println(s==t);//f
49        String r = "a"+"bc";
50        System.out.println(s==r);//f
51        System.out.println(t==r);//t
52        String u ="a"+new String("bc");
53        System.out.println(s==u);//f
54        System.out.println(r==u);//f
55        
56        //String[] s = new String[3,4];
57        System.out.println("--------------");
58        String str1 = "a"
59        String str2 = "bc"
60        String str3 = "a"+"bc"
61        String str4 = str1+str2; 
62        String str5 = "a"+str2;
63           
64        System.out.println(str3==str4); //f
65        System.out.println(str3==str5); //f
66        System.out.println(str3==str5); //f
67        str4 = (str1+str2).intern(); 
68        System.out.println(str3==str4); //t
69        System.out.println(str3==str5.intern());//t
70        
73
74    }

75
76}

77
78
79
80


posted on 2009-04-29 21:04 Frank_Fang 阅读(286) 评论(0)  编辑  收藏 所属分类: Java编程