1. public class String初始化存放地点解析 {
    2. @Test
    3. public void ceui() {
    4. //string字符串使用常量初始化时,常量存放在常量池中(栈中),过滤重复
    5. /**
    6. * 按照==的语法来看, 首先str0、str1、str111是三个不同的对象,
    7. * 常理来说,输出都会是false。然而程序的运行结果确实true、false。
    8. * 第二个输出false可以理解,第一个输出true就又让人费解了。
    9. * 我们知道一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,
    10. * 而堆内存中则存放new 出来的对象和数组。然而除此之外还有一块区域叫做常量池。
    11. * 像我们通常想String str0 = "小明"; 这样申明的字符串对象,其值就是存储在常量池中。
    12. * 当我们创建String str0 = "小明";这样一个对象之后,"小明"就存储到了常量池(也可叫做字符串池)中,
    13. * 当我们创建引用 String str1 = "小明"; 的时候,Java底层会优先在常量池中查找是否存在"小明",
    14. * 如果存在则让str1指向这个值,不会重新创建,如果常量池中没有则创建并添加的池中。
    15. * 这就是为什么答案是true 和false的原因。
    16. */
    17. String str0 = "小明";
    18. String str1 = "小明";
    19. //System.out.println("str0==str1:" + (str0 == str1));//true
    20. String str111 = "小明111";
    21. //System.out.println("str0==str111:" + (str0 == str111));//false
    22. /*
    23. * String字符串使用new初始化时先将常量放在常量池(栈)中,
    24. * 再将栈中的常量复制到堆中new为他分配的空间
    25. * 创建了两个对象,一个在常量池中,一个在堆中
    26. */
    27. String str2 = new String("小明");
    28. String str3 = new String("小明");
    29. System.out.println("str0==str2:" + (str0 == str2));//false
    30. System.out.println("str2==str3:" + (str2 == str3));//false
    31. /*两个字符串常量直接使用+拼接,则存放在栈中,除此之外其他的拼接都是放在堆中 */
    32. String str4 = "小" + "明";
    33. System.out.println("str0==str4:" + (str0 == str4));//true
    34. String str00 = "小";
    35. /*使用变量名和字符串拼接,存放在堆中*/
    36. String str5 = str00 + "明";
    37. System.out.println("str0==str1:" + (str0 == str5));//false
    38. System.out.println("str5==str2:" + (str5 == str2));//false
    39. }
    40. }