我们知道,JAVA中,内置类型都是在栈上分配内存的;而自定义类型是在堆上分配。
每个自定义类型的变量名都是一个引用,绑定到一个在堆上分配的自定义对象。
我的猜想是,这个引用就是一个指向堆上某位置的地址,这个变量名保存这个地址以达到绑定。
我的疑问是:这个引用(也就是这个地址)的信息是存在哪里的?堆上还是栈上?以何种方式?
谢谢。
每个自定义类型的变量名都是一个引用,绑定到一个在堆上分配的自定义对象。
我的猜想是,这个引用就是一个指向堆上某位置的地址,这个变量名保存这个地址以达到绑定。
我的疑问是:这个引用(也就是这个地址)的信息是存在哪里的?堆上还是栈上?以何种方式?
谢谢。
那段话是在THINKING IN JAVA中看到的啊。
原文如下:
此类变量(基本类型)直接存放数据值,并置于stack...
不知哪里错了。
private int age=100;
}
请问:age是不是内置基本类型?但是是在栈上上分配的吗?
我的理解,
基本类型 和 对象引用(包括数组引用) 同属于最基本的数据,
分配在当前所用的内存中。比如在方法内声明的局部变量(基本类型)、引用,都在栈上分配。
若是作为类中的非成员变量,
则放在 new 具体实例时,从堆中取的那块内存中。
静态成员等类推。
Java堆与栈
Java的堆是一个位于随机访问存储器(RAM)的运行时数据区。通常使用new操作符在堆中创建对象,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。 Java的栈也位于RAM,它的存取速度比堆要快,仅次于寄存器且据可以共享,主要存放一些基本类型的变量和对象的引用;但存在于栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义: int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,由于在栈中查找到3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。 这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。好了,我们再来看上面的例子:Integer i1 = 12;
Integer i2 = 12;
System.out.println(i1==i2); //true
由于是自动包装,对于从–128到127之间的值,它们被包装为Integer对象后,会存在内存中被重用,因此输出的是true;i1=new Integer(13);
i2=new Integer(13);
System.out.println(i1==i2); //flase
由于使用的是new操作符,而不是自动包装功能,Java在堆里面创建了两个Integer对象,分别与i1和i2关联,由于==对于对象比较的是引用,所以输出是false;然而下面的语句中实际上只创建了一个对象,这里又出现的别名的现象i1=i2=new Integer(14);
System.out.println(i1==i2);
因此用第一种方式创建多个int,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于Integer i = new Integer (int);的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。好了,这样以来相信下面的程序也不会为我们带来太多的疑惑了:view plaincopy to clipboardprint?
public static void main(String args[])
{
Integer i1=new Integer(13);
Integer i2=new Integer(13);
int i3=13;
System.out.println(i1==i2);
System.out.println(i2==i3);
System.out.println(i3==i1);
}
* Output
* false
* true
* true
*/ 本文来自CSDN博客,转载请标明出处:http://writeblog.csdn.net/PostList.aspx
int a=3,a在栈中,3在堆中
但是,楼主你的描述:
这个引用(也就是这个地址)
引用并不是地址只是堆中3的地址返回给这个引用a
也就是说,这个地址就是在堆中,只是栈得到了它,或者说指向了它,而它的值是3
首先看看
String s1 = new String("abc");
其实这条语句是下面两条语句的缩写,
String s1; //1
s1=new String(“abc”); //2
1. 在栈内存中定义一个名为s1的对String类的对像引用变量
2. 在堆内存开辟了一块空间用于存放字符串“abc”,将1定义的引用变量s1指向该空间。