QQ泡沫乐园 · 免费提供游戏辅助,破解软件,活动资讯,喜欢记得收藏哦!
综合软件_线报活动_游戏辅助_最新电影_最优质的的辅助分享平台

拘留池和String使用堆、栈、常量池的区别

泡沫乐园 2022-05-24 07:02

阅读帖子。

我今天看到一篇博客解释了 String 以及 String 如何使用堆、堆栈和常量池。讲的很仔细,很透彻,很接近底线,有一定难度。

原帖:

学习:

如果要了解String与堆、栈、常量池的关系,就必须要清楚的留字String对象。

实习生池(其中常量字符是实习生字符串对象)

公共语言运行时自动维护一个称为“实习池”的表,其中包含对程序中以编程方式声明或创建的每个唯一字符串的引用。因此,系统中只有一个具有特定值的字符串实例。

//代码1  
String sa=new String("Hello world");            
String sb=new String("Hello world");      
System.out.println(sa==sb);  // false       
//代码2    
String sc="Hello world";    
String sd="Hello world";  
System.out.println(sc==sd);  // true   

如博客中所述:

在代码 1 中:

String sa=new String("Hello world");开始执行,JVM已经在堆中为“Hello world”创建了一个detained string(值得注意的是,如果源程序中有一个“Hello world”字符串常量拘留通知书的序列码是干嘛用,那么它们都对应同一个heap中的detained strings) 然后用滞留字符串的值来初始化堆中new指令创建的新String对象。局部变量 sa 实际上存储了新堆对象的地址。此时,在JVM管理的堆中,存在两个字符串值相同的String对象:一个是被扣留的字符串对象,另一个是新创建的字符串对象。

String sb=new String("Hello world");执行时,滞留池中有“Hello world”,然后用这个detain对象从堆中初始化新的String对象,然后将地址存入sb。

所以 sa 和 sb 不一样。 (在堆中初始化后,有两个新的String对象)

在代码 2 中:

局部变量sc存储已经创建了滞留字符串地址的堆。比较sc运行的时候,用滞留字符串对象拘留通知书的序列码是干嘛用,直接保存对象地址

所以两者是一样的。

用 + 分析。

//代码1  
String sa = "ab";                                          
String sb = "cd";                                       
String sab=sa+sb;                                      
String s="abcd";  
System.out.println(sab==s); // false  
//代码2  
String sc="ab"+"cd";  
String sd="abcd";  
System.out.println(sc==sd); //true  

代码 1:

局部变量sa、sb存储了堆中两个滞留字符串对象的地址。 sa+sb执行时,JVM会先在堆中创建一个StringBuilder类,同时用sa指向的滞留字符串对象完成初始化,然后调用append方法完成滞留的合并操作sb指向的字符串,然后调用StringBuilder的toString()方法在堆中创建一个String对象,最后将新生成的String对象的堆地址存放在局部变量sab中。

字符串 s="abcd";执行:并且局部变量s存储了“abcd”对应的滞留字符串对象在常量池中的地址(sab和s中存储的地址不同)

代码 2:

字符串 sd="abcd"; “ab”+“cd”会在编译时直接合并成常量“abcd”,所以同一个字面常量“abcd”对应同一个滞留字符串对象,

String(大姐,诞生于JDK1.0时代)不可变字符序列

StringBuffer(二姐,诞生于JDK1.0时代)线程安全的变量字符序列

StringBuilder(小妹,诞生于JDK1.5时代)非线程安全的变量字符序列