public class StringTest {
public static void main(String[] args) {
/**
* 采用字面值的方式创建一个字符串时,
* JVM首先会去字符串池中查找是否存在这个对象,
* 如果不存在,则在字符串常量池中创建这个对象,然后将池中这个对象的引用地址返回给对象的引用s1,
* 这样s1会指向字符串常量池中这个字符串对象;
* 如果存在,则不创建任何对象,直接将池中这个对象的地址返回,赋给引用s2。
*/
String s1 = "hello";
String s2 = "hello";
System.out.println("s1==s2:"+(s1 == s2));//true
/**
* jvm对其有优化处理,也就是在编译阶段就会将这两个字符串常量进行拼接
*/
String s3 = "he" + "llo";
String s4 = "hel" + new String("lo");
System.out.println("s1==s3:"+(s1 == s3));//true
System.out.println("s1==s4:"+(s1 == s4));//false
/**
* 采用new关键字新建一个字符串对象时,
* JVM首先在字符串池中查找有没有这个字符串对象,
* 如果有,则不在池中再去创建这个对象了,直接在堆中创建一个字符串对象,
* 然后将堆中的这个对象的地址返回赋给引用;
* 如果没有,则首先在字符串池中创建一个字符串对象,然后再在堆中创建一个字符串对象,
* 然后将堆中这个字符串对象的地址返回赋给引用,
*/
String s5 = new String("hello");
System.out.println("s1==s5:"+(s1 == s5));//false
System.out.println("s4==s5:"+(s4 == s5));//false
/**
* 在1.6中,intern的处理是
* 先判断字符串常量是否在字符串常量池中,如果存在直接返回该常量,
* 如果没有找到,则将该字符串常量加入到字符串常量区,也就是在字符串常量区建立该常量;
*
* 在1.7中,intern的处理是
* 先判断字符串常量是否在字符串常量池中,如果存在直接返回该常量,
* 如果没有找到,说明该字符串常量在堆中,则处理是把堆区该对象的引用加入到字符串常量池中,
* 以后别人拿到的是该字符串常量的引用,实际存在堆中;
*/
String s6 = s5.intern();
System.out.println("s1==s6:"+(s1 == s6));//true
String s7 = "h";
String s8 = "ello";
/**
* 两个对象的相加,编译器不会进行优化,相加的结果存在堆中
*/
String s9 = s7 + s8;
System.out.println("s1==s9:"+(s1 == s9));//false
System.out.println("s5==s9:"+(s5 == s9));//false
/**
* 字符串对象在JVM中可能有两个存放的位置:字符串常量池或堆内存。
*
* 使用常量字符串初始化的字符串对象,它的值存放在字符串常量池中;
* 使用字符串构造方法创建的字符串对象,它的值存放在堆内存中;
*/
System.out.println("------------------------------");
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
/**
* 范围在-128~127存在在常量池,范围以外则在堆区进行分配。
*
* Float和Double这两个类并没有对应的常量池。
*/
System.out.println(c == d);//true
System.out.println(e == f);//false
/**
* 包装类的“==”运行符在不遇到算术运算的情况下不会自动拆箱,
* 以及他们的equals()方法不处理数据类型的关系,
* 通俗的讲也就是“==”两边如果有算术运算,那么自动拆箱和进行数据类型转换处理,比较的是数值等不等。
*/
System.out.println(c == (a + b));//true
System.out.println(c.equals(a + b));//true
System.out.println(g == (a + b));//true
/**
* Long的equals方法会先判断是否是Long类型。
*/
System.out.println(g.equals(a + b));//false
String a1 = new String("hello");
String intern1 = a1.intern();
String a2 = "hello";
System.out.println(a1 == a2);//false
System.out.println(intern1 == a2);//true
String a3 = new String("hello") + new String("hello");
String intern3 = a3.intern();
String a4 = "hellohello";
System.out.println(a3 == a4);//true (1.6false)
System.out.println(intern3 == a4);//true
System.out.println(a3 == intern3);//true
String b1 = new String("hello");
String b2 = "hello";
String intern_1 = b1.intern();
System.out.println(b1 == b2);//false
System.out.println(intern_1 == b2);//true
String b3 = new String("hello") + new String("hello");
String b4 = "hellohello";
String intern_3 = b3.intern();
System.out.println(b3 == b4);//false
System.out.println(intern_3 == b4);//true
String str1 = "aaa";
String str2 = "bbb";
String str3 = "aaabbb";
String str4 = str1 + str2;
String str5 = "aaa" + "bbb";
System.out.println(str3 == str4); // false
System.out.println(str3 == str4.intern()); // true
System.out.println(str3 == str5);// true
}
}