一.栈的作用
1. 栈的存放
- 局部变量
- 堆中对象的引用(对象在堆内存中的地址)
一个对象的大小无法估计,但是一个对象的引用只占4byte
基本数据类型的变量没有什么存储区域的说法,内存中分为两类进行存储
-
- 全局变量存储在堆中
- 局部变量存储在栈中
2. 栈的属性
- 栈的创建方式
- 每条线程都有一个独立的栈,在线程创建时创建
二.栈的操作
1. 栈的存取顺序是先进后出,后进先出,就像是手枪弹夹,后进去的先打出来;
2. 代码模拟
public class SQ {
//先规定栈的最大容量
Object[] objs ;
//获取当前栈容量
int size;
public SQ(int MaxLen){
this.objs = new Object[MaxLen];
}
//进行压栈操作(就是在栈中存入内容)
public void push(Object x){
System.out.println("压栈操作,压入内容为"+( objs[size++] = x)); //先给当前指针位置赋值,然后指针变大
}
//弹栈操作
public void popu() {
System.out.println("弹出栈顶内容:"+objs[size-1]);//获取栈顶数据,然后弹出栈中,栈容量减少
size--;
}
//获取栈内所有数据
public void getAllStack() {
System.out.println("栈顶到栈底所有数据为");
for (int i = size-1; i >= 0; i--) {
System.out.println(objs[i]+" ");
}
}
public static void main(String[] args) {
SQ s = new SQ(20);
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.getAllStack();
s.popu();
s.popu();
s.getAllStack();
}
}
output:
压栈操作,压入内容为1
压栈操作,压入内容为2
压栈操作,压入内容为3
压栈操作,压入内容为4
栈顶到栈底所有数据为
4
3
2
1
弹出栈顶内容:4
弹出栈顶内容:3
栈顶到栈底所有数据为
2
1
三.栈和栈帧
1.栈帧的作用和定位
- java栈以帧为单位来保存线程的状态
- jvm对java栈只进行两种操作
- ----以帧为单位的压栈和弹栈
2.局部变量表
局部变量,他是class文件里面的内容,加载后被传递到方法区,参见Class类详解
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
代码执行的时候是执行一个方法,执行完,返回方法的上一个代码块继续往下执行后面的内容。这样的话是不是就是一个栈结构了?先进后出。方法一边执行,一边往栈里面存数据,等执行完了就取出数据(取出的是返回值,是最后一个存进去的 栈结构是后进先出),然后执行外面的代码。这么说你可能不明白,我给你举个例子。
int sub(int a,int b){
return a+b;
}
int c = sub(2,3);//注意执行这条语句的时候是不是执行了一个方法?
//那么语句执行的时候是要从左往右执行的对吧,但是事实的逻辑却是先算出来sub(2,3)这个方
//法的返回值,然后再把返回值(5)赋值给 c ,那么这个怎么实现,肯定是一个栈的数据结构,编译的时候先把”int c = “入栈,然后再把 sub(2,3),入栈,执行的时候,从栈里面取,取的第一个肯定是sub(2,3)吧?于是就计算出等于5,继续取,取出了int c =,然后就和5对接上了,就把值赋给c了。这只是一个小例子。
道理是这样,但是具体的存取可不是这样的哦。具体的存取应该分的非常细腻,应该是按照java语法的最小单位来往栈里存取的。说白了一句话,程序运行的时候的先后顺序是跟人大脑想问题的顺序一样的,但是代码不是按照这样的顺序写的(从左到右),于是就用栈结构来达到这样的效果。