堆和栈都是Java中在RAM(读写存储器)存储数据的地方。Java自动管理堆和栈,无需程序员设定。
不同之处:
1.Java的堆是一个运行时数据区,类的对象从中分配空间。例如 new()和newarray创建的对象和数组。堆得优势是它可以动态的分配内存大小,生存周期也不用告诉编译器,对象所需的内存空间只有在运行创建后方可确定。但缺点是由于要动态分配内存,读取速率相较于栈较慢。
2.Java的栈的内存大小和生存周期是必须确定的,缺乏灵活性。优点是读取速率较快,仅次于寄存器,以及数据可共享。
栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和引用对象,栈里存的却是堆的首地址名;就像引用变量。
3.说明
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指向这个地址。
String str1= new String("aaa");
String str2 = "aaa";
使用new关键字声明的String类则一定会新开辟一个堆内存空间,同时以String为模板常见一个值为aaa的对象,同时将str1将指向值为aaa的地址。
而第二种是先在栈中创建一个对String类的对象引用变量str2,然后查找栈中有没有存放"aaa",如果没有,则将"aaa"存放进栈,并令str2指向”aaa”,如果已经有”aaa” 则直接令str指向“aaa”。
引用变量
我们经常会这样写 ,sVehicle veh1 = new Vehicle();
通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。
1)右边的“new Vehicle”,是以Vehicle类为模板,在堆空间里创建一个Vehicle类对象(也简称为Vehicle对象)。
2)末尾的()意味着,在对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。
3)左边的“Vehicle veh 1”创建了一个Vehicle类引用变量。所谓Vehicle类引用,就是以后可以用来指向Vehicle对象的对象引用。
4)“=”操作符使对象引用指向刚创建的那个Vehicle对象。
我们可以把这条语句拆成两部分:
Vehicle veh1;
veh1 = new Vehicle();
效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。
不同之处:
1.Java的堆是一个运行时数据区,类的对象从中分配空间。例如 new()和newarray创建的对象和数组。堆得优势是它可以动态的分配内存大小,生存周期也不用告诉编译器,对象所需的内存空间只有在运行创建后方可确定。但缺点是由于要动态分配内存,读取速率相较于栈较慢。
2.Java的栈的内存大小和生存周期是必须确定的,缺乏灵活性。优点是读取速率较快,仅次于寄存器,以及数据可共享。
栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和引用对象,栈里存的却是堆的首地址名;就像引用变量。
3.说明
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指向这个地址。
String str1= new String("aaa");
String str2 = "aaa";
使用new关键字声明的String类则一定会新开辟一个堆内存空间,同时以String为模板常见一个值为aaa的对象,同时将str1将指向值为aaa的地址。
而第二种是先在栈中创建一个对String类的对象引用变量str2,然后查找栈中有没有存放"aaa",如果没有,则将"aaa"存放进栈,并令str2指向”aaa”,如果已经有”aaa” 则直接令str指向“aaa”。
引用变量
我们经常会这样写 ,sVehicle veh1 = new Vehicle();
通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。
1)右边的“new Vehicle”,是以Vehicle类为模板,在堆空间里创建一个Vehicle类对象(也简称为Vehicle对象)。
2)末尾的()意味着,在对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。
3)左边的“Vehicle veh 1”创建了一个Vehicle类引用变量。所谓Vehicle类引用,就是以后可以用来指向Vehicle对象的对象引用。
4)“=”操作符使对象引用指向刚创建的那个Vehicle对象。
我们可以把这条语句拆成两部分:
Vehicle veh1;
veh1 = new Vehicle();
效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。