String s1 = "JavaEEHadoop"; //在字符串常量池中创建 "JavaEEHadoop"
String s2 = new String("JavaEEHadoop").intern(); //会将字符串常量池中 "JavaEEHadoop" 地址 返回s2
System.out.println(s1 == s2); true/**
* 此代码会在字符串常量池中 创建 "JavaEE"、”Hadoop“
* 会使用StringBUilder来拼接,最后执行toString方法
*
* 此时在堆中是存在值为 "JavaEEHadoop" 的字符串对象的
*/
String s1 = new String("JavaEE") + new String("Hadoop");
/**
* 由于s1在堆中已存在,因此为了节省空间,字符串常量池中并不会创建 "JavaEEHadoop"
* 而是保存 堆中对象的引用
*/
s1.intern();
/**
* 由于此刻字符串常量池中已存在,因此s2会指向常量池中 堆中对象的引用
*/
String s2 = "JavaEEHadoop";
System.out.println(s1 == s2); trueString s1 = "JavaEE";
String s2 = "Hadoop";
String s3 = "JavaEEHadoop";
/**
* 编译器优化 为 JavaEEHadoop,s3 == s4 为true,在字符串常量池中同一份
*/
String s4 = "JavaEE" + "Hadoop";
System.out.println(s3 == s4); true
/**
* 如果拼接符号的前后出现了变量
* 1、StringBuilder.toString中 s = new StringBuilder();
* 2、s.append("JavaEE");
* 3、s.append("Hadoop");
* 4、s.toString(); -->类似于 new String(char[])
* 但跟String s = new String("JavaEEHadoop")不一样
* 由于StringBuilder.toString中new String中参数是char[]数组
* 因此并不会在字符串常量池中创建 ”JavaEEHadoop“
*/
String s1 = "JavaEE"; //字符串常量池中 "JavaEE"
String s2 = "Hadoop"; //字符串常量池中 "Hadoop"
String s3 = "JavaEEHadoop";
String s4 = s1 + "Hadoop";
String s5 = s1 + s2;
System.out.println(s3 == s4); false
System.out.println(s3 == s5); false
/**
* final修饰的string变量相加时,编译器会优化为 ab,不会用StringBuilder拼接
* s11 == s12 为true,在字符串常量池中同一份
* s12会被编译器优化为 "ab"
*/
final String s1 = "a";
final String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2;
System.out.println(s2 == s4); true/**
* 创建了1个或2个
* 执行步骤,对应字节码步骤
*
* 1、堆中开辟String对象空间 new #8
* 2、如果 "ab" 在字符串常量池中存在,那么久不创建,如果不存在则创建
* 3、初始化String对象
*/
String s1 = new String("ab");
/**
* 字节码
*/
步骤1、new #17
步骤1、dup
步骤2、ldc #14
步骤3、invokespecial #18 >
/**
* 如果字符串常量池中 "a"、"b"不存在,那么会创建6个对象
*
* 执行步骤对应字节码步骤
* 1、堆中开辟StringBuilder对象空间,初始化StringBuilder对象
* 2、堆中开辟String对象空间
* 3、在字符串常量池中创建 "a"
* 4、初始化String对象
* 5、执行append方法
*
* 6、堆中开辟String对象空间
* 7、在字符串常量池中创建 "b"
* 8、初始化String对象
* 9、执行append方法
* 10、执行toString方法
* StringBuilder对象toString方法执行说明,由于返回的是String对象,因此会执行toString方法
* 11、堆中开辟String对象空间
* 由于调用的是new String(char[])构造方法
* 因此并不会在字符串常量池中创建 "ab"
*/
String s1 = new String("a") + new String("b");
/**
* 字节码文件
*/
步骤1、new #8
步骤1、dup
步骤1、invokespecial #9 >
步骤2、new #17
步骤2、dup
步骤3、ldc #12
步骤4、invokespecial #18 >
步骤5、invokevirtual #10
步骤6、new #17
步骤6、dup
步骤7、ldc #13
步骤8、invokespecial #18 >
步骤9、invokevirtual #10
步骤10、invokevirtual #11
步骤11、new #80
步骤11、dup
//我们可以看到toString方法中并没有 在字符串常量池中创建 "ab"
aload_0
getfield #234
iconst_0
aload_0
getfield #233
invokespecial #291 >
areturn 提示:这里对文章进行总结:
建议大家不要卷、不要卷、不要卷
| 留言与评论(共有 0 条评论) “” |