java中String和new String还有对象中的String字符串在内存中的存储
2018-01-25 18:04
387 查看
参考自:http://blog.csdn.net/zhangjg_blog/article/details/18319521 的博客,很多知识和代码都来源此,感兴趣的同学可以去看看
一直以来,所有人都说,java中的String类型是不可变的,可是为什么不可变确很少有人说的透彻,String和new
String的区别,对象中的String和直接定义一个String是否有区别,一直都是一知半解。看了很多文档都是各种猜测,没有具体代码来证明。今天看了上面的博客做了一些测试,有一些心得。String类型一直是一个特殊的数据类型,在创建的时候就是不可变的,会在Stringconstant pool中创建一个常量,当我们再次创建一个字符串的时候,jvm会先去String
constant pool 中检索这个这个常量是否存在,如果存在则将引用返回,如果不存在,则创建新的常量,然后将引用返回。那么使用new String的方法创建?或者是在一个对象的实例中创建一个字符串?内存中这个值会如何存储?是在Heap中直接开辟空间存储,还是会在Stringconstant
pool 中创建,然后在Heap中创建一个引用?接下来,通过代码来证明,在内存中String究竟是如何存储的
首先是String和new String的区别
代码执行结果
根据结果可以判断,无论是String还是new String最终都指向了String
constant pool中,只不过是String直接指向了Stringconstant pool中。而new
String是在Heap中创建了一个指向String constant pool中的引用。那么,对象中String是否也是这样的?那么我们是否可以这样推测,在java中所有的String类型的字符串,最终都会指向Stringconstant
pool 中?
然后是String和Object的区别
代码执行结果
根据执行结果可以看出,不同对象中的String值相等时,其指向的是同一个String constant pool中的地址,如果我们修改了其中一个值得时候,所有的引用都会发生改变,而且其内存地址的比较并没有发生变化。所以我们的推测应该是正确的,因时间关系,没有了测试数组和其他的关于String类型的字符串是否也是如此,不过根据上面的结果,我们应该可以大胆猜测,java中,如果定义了String类型的字符串,最终的都存在String
constant pool 中。如果有什么意见或建议请在下方留言,再次感谢原博主
一直以来,所有人都说,java中的String类型是不可变的,可是为什么不可变确很少有人说的透彻,String和new
String的区别,对象中的String和直接定义一个String是否有区别,一直都是一知半解。看了很多文档都是各种猜测,没有具体代码来证明。今天看了上面的博客做了一些测试,有一些心得。String类型一直是一个特殊的数据类型,在创建的时候就是不可变的,会在Stringconstant pool中创建一个常量,当我们再次创建一个字符串的时候,jvm会先去String
constant pool 中检索这个这个常量是否存在,如果存在则将引用返回,如果不存在,则创建新的常量,然后将引用返回。那么使用new String的方法创建?或者是在一个对象的实例中创建一个字符串?内存中这个值会如何存储?是在Heap中直接开辟空间存储,还是会在Stringconstant
pool 中创建,然后在Heap中创建一个引用?接下来,通过代码来证明,在内存中String究竟是如何存储的
首先是String和new String的区别
public static void main(String[] args) throws Exception { String hello="hello world"; String xx=new String("hello world"); String yy="hello world"; //输出判断内存地址是否相等 System.out.println("xx==hello : "+ (xx==hello)); System.out.println("yy==hello : "+ (yy==hello)+"\n"); //通过反射修改hello的value值 Field hello_field=String.class.getDeclaredField("value"); hello_field.setAccessible(true); char[] value=(char[])hello_field.get(hello); value[5]='_'; //首先输出修改结果 System.out.println("Hello: "+hello+"\n"); //然后判断内存地址是否有变化 System.out.println("xx==hello : "+ (xx==hello)); System.out.println("yy==hello:"+(hello==yy)); System.out.println("xx==yy:"+(xx==yy)+"\n"); //最后输出所有值的结果 System.out.println("xx: "+xx); System.out.println("yy: "+yy); System.out.println("Hello: "+hello); }
代码执行结果
xx==hello : false yy==hello : true Hello: hello_world xx==hello : false yy==hello:true xx==yy:false xx: hello_world yy: hello_world Hello: hello_world
根据结果可以判断,无论是String还是new String最终都指向了String
constant pool中,只不过是String直接指向了Stringconstant pool中。而new
String是在Heap中创建了一个指向String constant pool中的引用。那么,对象中String是否也是这样的?那么我们是否可以这样推测,在java中所有的String类型的字符串,最终都会指向Stringconstant
pool 中?
然后是String和Object的区别
import java.lang.reflect.Field; public class StringTest { public String name="hello world"; public String phone; public StringTest(String phone) { // TODO Auto-generated constructor stub this.phone=phone; } public static void main(String[] args) throws Exception { StringTest a = new StringTest("hello world"); StringTest b = new StringTest("hello world"); String c = "hello world"; String e = new String("hello world"); //首先判断不同对象中的字符串地址是否相等 System.out.println("a.name==a.phone:"+(a.name==a.phone)); System.out.println("a.name==b.phone:"+(a.name==b.phone)); System.out.println("a.name==c:"+(a.name==c)); System.out.println("e==c:"+(e==c)+"\n"); //然后修改c在内存中的值 Field hello_field=String.class.getDeclaredField("value"); hello_field.setAccessible(true); char[] value=(char[])hello_field.get(c); value[5]='_'; //首先判断不同对象中的字符串地址是否相等 System.out.println("a.name==a.phone:"+(a.name==a.phone)); System.out.println("a.name==b.phone:"+(a.name==b.phone)); System.out.println("a.name==c:"+(a.name==c)); System.out.println("e==c:"+(e==c)+"\n"); //直接输出值判断是否发生变化 System.out.println("a.name: "+a.name); System.out.println("b.name: "+b.name); System.out.println("a.phone: "+a.phone); System.out.println("b.phone: "+b.phone); System.out.println("c: "+c); System.out.println("e: "+e); } }
代码执行结果
a.name==a.phone:true a.name==b.phone:true a.name==c:true e==c:false a.name==a.phone:true a.name==b.phone:true a.name==c:true e==c:false a.name: hello_world b.name: hello_world a.phone: hello_world b.phone: hello_world c: hello_world e: hello_world
根据执行结果可以看出,不同对象中的String值相等时,其指向的是同一个String constant pool中的地址,如果我们修改了其中一个值得时候,所有的引用都会发生改变,而且其内存地址的比较并没有发生变化。所以我们的推测应该是正确的,因时间关系,没有了测试数组和其他的关于String类型的字符串是否也是如此,不过根据上面的结果,我们应该可以大胆猜测,java中,如果定义了String类型的字符串,最终的都存在String
constant pool 中。如果有什么意见或建议请在下方留言,再次感谢原博主
相关文章推荐
- Java中变量,对象,字符串等在内存中的存储区域
- java对String字符串对象的创建及管理
- (原创)深入研究java对String字符串对象的创建以及管理
- 三分钟理解Java中字符串(String)的存储和赋值原理
- 深入研究java对String字符串对象的创建以及管理
- 深入研究java对String字符串对象的创建以及管理
- 深入研究java对String字符串对象的创建以及管理
- 20110327-8.1-sstream定义的类型用于读写存储在内存中的string对象
- 简述c++中string对象的内存分配策略?如何获得其可存储的最大字节
- 深入研究java对String字符串对象的创建以及管理
- 详解Java String字符串对象的创建及管理(1)
- 深入研究java对String字符串对象的创建以及管理
- 【转】深入研究java对String字符串对象的创建以及管理
- java对String字符串对象的创建以及管理
- 深入研究java对String字符串对象的创建以及管理
- Java对String字符串对象的创建,管理和“+”运算符的实现
- 深入研究java对String字符串对象的创建以及管理
- Java对String字符串对象的创建,管理和“+”运算符的实现
- 深入研究java对String字符串对象的创建以及管理
- C#和JAVA对象在内存中的存储