http://lichenhao.javaeye.com/blog/499147
- public class StringTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- //先在String pool中查找,没有则创建,并且在堆中创建对象,返回堆中对象地址
- String s = new String("123");
- //先在String pool中查找,有则返回对象的地址
- String s1 = "123";
- //先在String pool中查找,有,只在堆中创建对象
- String s2 = new String("123");
- System.out.println(s==s1);
- System.out.println(s==s2);
- System.out.println(s1==s2);
- /*
- * intern
- public String intern()返回字符串对象的规范化表示形式。
- 一个初始为空的字符串池,它由类 String 私有地维护。
- 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
- 它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
- 所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。字符串字面值在 Java Language Specification 的 §3.10.5 定义。
- 返回:
- 一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。
- */
- System.out.println(s==s.intern()); //false
- System.out.println(s1==s1.intern()); //true
- System.out.println(s.intern()==s2.intern()); //true 都指向的是字符串池的引用
- System.out.println("-------------------------");
- String hello = "hello";
- String he = "he";
- String llo = "llo";
- System.out.println(hello=="he"+"llo"); //true "he"+"llo" “+”java判断pool中是否存在hello,有则返回字符串池中的对象
- System.out.println(hello == "he" + llo); //false "he" + llo 在堆中新创建对象
- }
- }
public class StringTest {
/**
* @param args
*/
public static void main(String[] args) {
//先在String pool中查找,没有则创建,并且在堆中创建对象,返回堆中对象地址
String s = new String("123");
//先在String pool中查找,有则返回对象的地址
String s1 = "123";
//先在String pool中查找,有,只在堆中创建对象
String s2 = new String("123");
System.out.println(s==s1);
System.out.println(s==s2);
System.out.println(s1==s2);
/*
* intern
public String intern()返回字符串对象的规范化表示形式。
一个初始为空的字符串池,它由类 String 私有地维护。
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。字符串字面值在 Java Language Specification 的 §3.10.5 定义。
返回:
一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。
*/
System.out.println(s==s.intern()); //false
System.out.println(s1==s1.intern()); //true
System.out.println(s.intern()==s2.intern()); //true 都指向的是字符串池的引用
System.out.println("-------------------------");
String hello = "hello";
String he = "he";
String llo = "llo";
System.out.println(hello=="he"+"llo"); //true "he"+"llo" “+”java判断pool中是否存在hello,有则返回字符串池中的对象
System.out.println(hello == "he" + llo); //false "he" + llo 在堆中新创建对象
}
}
源码分析
1.执行第一行后,内存中有几个对象?
2个即堆中的对象和String pool中的对象,内容都是abc,因为存在String pool.String类是不可变类,内容确定就不能改变,new关键字在生成对象时,首先在pool中查找是否有相同的内容,如果没有则在pool中创建对象并赋值,然后在堆中创建对象,值相同,本例中都为abc字符串,s为堆中对象的引用。
2.判断s==s1,s==s2,s1==s2?
执行第二行后,内存中未创建新的对象,首先在String pool中查找是否有相同内容的对象,因为在第一行语句中已经创建内容为abc字符串,所以不再创建对象,s1为pool中值为abc的对象的引用。
执行第三句后,堆中又新增有一个值为abc的对象,pool中不变,s2为其引用。
因为s,s1,s2为不同的引用,所以不相等。
ps:==判断是否指向同一个对象,八个原生数据类型判断值是否相同。
判断s==s.intern()
false,intern方法为在方法调用时,如果pool中包含一个字符串和对象中的字符串相等(equal),则返回pool中的对象地址,否则在pool中增加一个内容相同的对象,并返回原对象地址。