java中堆栈对比

 

栈的优点是存取速度快,至少比堆快。但由于栈自身数据结构的特点,导致存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。(这里就可见方法栈为什么用stack这种数据结构了,首先每个方法对应的形参和非静态变量数量和大小是固定的,第二在调用方法时生成栈,压栈该方法结束时出栈,生命周期是确定的。)

 

堆的优势是可以动态分配内存大小,也不用管他的生命周期,jvm的垃圾收集器会在适当时候自动收走不再使用的数据。缺点是堆得存取速度较栈为慢。

 

方法中不同类型数据的定义与存储

 

一种是基本类型(primitive types)共8种,int、short、long、byte、float、double、boolean、char。基本类型定义是通过如 int a = 3;的形式来定义的,这里a称为自动变量。自动变量存的是字面值而不是类的引用。这里a是一个指向int类型的引用,指向3这个字面值。这些字面值大小可知,生存期可知存于栈中,另外栈有个很重要的特殊性,就是存在栈中的数据可以共享。如:

int a = 3;

int b = 3;

编译器先处理int a =3;首先它会在栈中创建一个变量为a的引用,然后在栈中查找字面值为3的地址,没找到就开辟一个存放3的地址,再把a指向这个地址。int b = 3; 则b指向这个地址。

 

特别注意的是字面值的引用与对象的引用不同。这时另b = 4;不会修改这个字面值,而是重新再栈中寻找4的地址。

 

 

String比较特殊

String a = new String("xx");的形式创建则是在堆中建一个新对象,a的引用指向这个对象

String a = “xx”;的话(小细节,不同于Float等String并没有string这个数据类型所以怎么都要指向String对象)

1.先定义一个名为a的堆String类对象的引用;

2.在栈中查找“xx”值的地址,没有则开辟存放字面值“xx”的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,并在栈中该地址旁记下这个对象o。返回这个o地址给a

 

String a = "abc"

String b = "abc"

System.out.println( a == b ) //true

b = "bc"  则b指向新地址

 

事实上String类被设计成不可改变(immutable)的类,当String变量需要经常变换值时,应该考虑使用StringBuffer类来提高效率。

 

另:equal比较值,==比较是否同一个对象