String对象问题曾困扰我很长时间,总是不太明白它与基本数据类型之间的区别,看了java内存分配,得到了一点启发,下面从堆和栈的角度看一下String对象在内存中是如何操作的。
首先看一下堆和栈的区别
栈:栈中存放的是基本类型的变量或者引用类型的变量。其中局部变量是通过数组的索引来访问,操作数栈通过栈操作才实现。局部变量有利于内存空间的高效利用, 方法运行完就回收,而对于类成员变量,只要对象还在,即使方法运行结束,成员变量还是存在。
堆:存放通过new关键字新建的对象和数组。声明的对象是在堆内存中初始化,对象的数据存放在堆中,不可以直接访问。引用变量保存了堆中对象的地址,它保存在栈中,用来引用堆中的对象。
栈代表了运行的逻辑,堆代表了运行时的数据。
我们对堆和栈有了基本的理解,现在我们步入正题,String对象。
首先我们从一个例子来看。
String s1 = "hello";
String s2 = new String("hello");
String s3 = "hello";
String s4 = new String("hello");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s2 == s4);
答案是:false, true, false
首先我们看一下 String s2 = new String("hello"), 和正常的创建对象一样,通过new String("hello") 在堆内存中创建了一个String对象,堆给这个对象分配内存空间,对象的内容是”hello“,记住对象保存在堆中。唯一不同的是JVM为string设置了一个常量池,用new关键字的同时,在常量池中也会产生一个“hello”对象,也就是说 new String("hello")会在堆和字符串常量池中分别创建一个对象。s2就是所谓的引用变量,s2是保存在栈中,它里面的内容是这个对象在堆中的内存地址,正如上面所说对象是不能直接调用的,只能通过引用变量来调用。并且new一次,堆就会给这个对象分配内存空间。对于==操作符,只有当两个引用变量指向同一个对象时才返回true,因此s2 == s4返回false。
对于String s1 = "hello", 它首先会在字符串常量池中寻找是否有‘’hello”,如果存在,就把指向“hello”的引用变量里面的值赋值给新的引用变量,在这个例子中就是把s1里面的内容赋值给s3,他们实际上是指向的同一个对象,因此s1 == s3返回true。如果字符串常量池中不存在“hello”,此时首先在常量池中创建一个对象,然后让当然的引用变量指向这个地址。对于这个例子,s1指向的是常量池里的“hello”,s2指向的是堆中的“hello”,因此s1 == s2返回false。JVM是为了提高效率才设计了这样的操作。如果每次都用new关键字,会造成内存的浪费。
个人的一点体会,如有错误的地方希望大家指出!
分享到:
相关推荐
String对象常用的属性的方法String对象常用的属性的方法
此程序是向大家展示js脚本中string对象的基本应用
String3.1-java堆和栈---马克-to-win java视频 马克Java社区 马克towin
86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点.zip86.java中String对象的特点....
String对象的创建问题,分为:编译期和执行期 详细的讲解String对象创建问题
CString对象和string对象的相互转化问题,以及他们呢的用法
在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存...
对String创建几个对象代码详解,包括字符串相加,对象相加等等
string对象的操作string对象的操作
string 、对象 、json之间相互互转 ,包含jar包测试类,做了简单的,能使而已!
读入未知数目的string对象.cpp
偶然看到一道面试题,Java在实例化一个类的时候,数据在堆和栈中是如何存放的? public class A{ public int i=1; public static A a1 = new A(); public static void mian(String args[]){ int c = ...
Java String对象的经典问题,有关String类的介绍
String对象 6.4.1 String对象 1、创建String对象 在JavaScript中可以使用一对单引号或双引号将任意多个字符引起来,即生成字符型数据。这些字符型数据实际上也是构造函数String的实例,即String对象。 6.4.1 String...
Java中颜色的String和Color对象之间的互相转换
JavaScript String 对象参考手册
创建string对象过程的内存分配&&包含多个例子,更加容易理解~~
最近在网上经常看到String对象的问题,现将String对象的内存分析进行分享
String和string区别以及string详解
memset初始化std::string对象时,按字节顺序将std::string对象所在空间清零,破坏了std::string对象的成员结构,使Myroxy指针资源变为野指针,操作其迭代器会出现不可预知的异常,在存储字符串时可能分配了不必要的...