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技术干货!
▼微信扫一扫下图↓↓↓二维码关注