String字符串创建与存储机制

Java内存可以粗略的区分为堆内存(Heap)和栈内存(Stack),堆中存放的是对象实例,而栈中存放的则是方法调用过程中的局部变量或引用等。

在Java语言中,字符串的生命与初始化有如下两种方式:

 1. 初始化 

String str1 = "helloJava";

String str2 = "helloJava"; 

在JVM中存在存在一个字符串常量池,用于存放特定的字符串对象,可以被共享使用。str1和str2引用的是同一个字符串常量池里的对象。当创建一个字符串常量时,如"helloJava",首先会在常量池中查找是否已经存在相同的字符串(通过string.equals()方法判断,如果返回true,则认为是相同的字符串),如果存在,则直接获取其引用,不需要重新创建对象;若不存在,则会首先创建这个对象,然后把它加入到字符串常量池中,再将它的引用返回。

由于String类是不可变类,一旦创建好后就不能修改,因此String对象可以被共享而且不会导致程序混乱。

 2. 创建对象 

String str3 = new String("helloJava"); 
String str4 = new String("helloJava"); 

str3和str4是通过new关键字创建的两个不同的对象,在内存中的地址是不同的。 

String str3 = new String("helloJava")这条语句可以分解为两个过程:

1)创建对象

即new String("helloJava"),调用String类的构造方法,传入一个字符串常量,等价于两个操作:"helloJava"和new String()。如果字符串常量池中不存在"helloJava",则会创建常量"helloJava",并添加到常量池中;若存在则不创建,new String()会在堆中创建一个新的对象,因此str3和str4分贝指向堆中不同的对象。
2)赋值

即String str3 = ,将一个String类型的引用赋值给str3变量,这个过程不会创建新的对象。

 

 举例说明 :

String s1 = "helloJava";//把"helloJava"放入常量池中,编译时产生
String s2 = "hello"+"Java";//把"hello"和"Java"转换成"helloJava"放入常量池中
String s3 = "helloJava";//引用常量池中的对象,不会重新创建对象
String s4 = new String("helloJava");//运行时把"helloJava"放入堆里面,在堆中创建一个对象
String s5 = new String("helloJava");//在堆中又创建一个新的对象

 

 存储图例 :

 

欢迎关注微信公众号【Java典籍】,收看更多Java技术干货!

  ▼微信扫一扫下图↓↓↓二维码关注

 

posted @ 2019-03-11 20:20  冰湖一角  阅读(632)  评论(0编辑  收藏  举报