JAVA 方法的入栈出栈问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 方法的入栈出栈问题相关的知识,希望对你有一定的参考价值。

JAVA 的方法入栈是把方法复制到栈内存里再执行 还是有指向这个方法的地址去调用这个方法然后执行?

之所以有这个疑问是因为:方法都存放在方法区里,而所有方法的执行都是在JVM栈中实现的,所以要把方法“入栈”,那么,入栈这个概念 到底是把所要用的方法复制到栈中执行, 还是栈中有个类似指针的引用地址指向方法区中的所用方法然后在方法区执行??

如果是在方法区执行的话,那入栈入到底入了什么 出栈又出了什么!?

你得明白栈的定义。代码执行的时候是执行一个方法,执行完,返回方法的上一个代码块继续往下执行后面的内容。这样的话是不是就是一个栈结构了?先进后出。方法一边执行,一边往栈里面存数据,等执行完了就取出数据(取出的是返回值,是最后一个存进去的 栈结构是后进先出),然后执行外面的代码。这么说你可能不明白,我给你举个例子。

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语法的最小单位来往栈里存取的。说白了一句话,程序运行的时候的先后顺序是跟人大脑想问题的顺序一样的,但是代码不是按照这样的顺序写的(从左到右),于是就用栈结构来达到这样的效果。
这么说,明白了吗?追问

你说的我看明白了 ,很详细,谢谢,不过还是有一个问题:在执行的时候,执行到了sub(2,3),他是怎么读取方法区中的那段sub的方法代码的?还有就是2+3这个计算的过程是发生在栈中内存吗?如果是,那么把 sub(2,3)入栈,入栈的内容是不是就是整个sub代码:int sub(int a,int b)
return a+b;

也就是把这块代码的字节码复制到了栈内存中??

参考技术A 和你说下 堆和栈 都属于内存中 当然java虚拟机内存里还有一部分static 静态常量存放的区域也属于内存中

你说的那些方法啊什么的 具体方法的代码都是储存在硬盘中的 只有当类加载的时候才把这个类存放在方法区里

Object obj=new Object()

存放通常说的对象的引用 obj 就是存一个名字

存放通常说的实体对象 即 栈中的引用指向堆中的一个具体对象new Object() 在堆中开辟内存 放对象内容

当然特殊的情况就是java 基础变量 int a=1 a 和 1 都存储在栈中

针对什么
入栈出栈
因为java虚拟机自己有回收垃圾的机制

什么是垃圾
就是栈中存放的一些引用 没有指到一个具体的实例对象

还有就是局部变量跑完了自己的方法体

被虚拟机干掉

算法专题卡特兰数(计数数列)

Catalan数列:1 1 1 2 5 14 42 132 429 1430 4862 16796

【计数映射思想】

参考:卡特兰数 — 计数的映射方法的伟大胜利

计数映射:将难以统计的数映射为另一种形式的可以统计的数。

一、入栈出栈序

n个数字,有多少种合法的入栈出栈序列?n=3时的合法序列之一:+1,-1,+1,+1,-1,-1

对于n个数字,就是要在2n个1中添加n个“+”,则序列总数C(2n,n)。

对于未入栈先出栈的不合法情况,在其第一次前缀和为-1时,将前面的所有符号反转,此时整个序列有n+1个“+‘和n-1个’-‘,每个不合法序列都映射为2n个1中添加n+1个‘+‘构成的序列。

正向:每个不合法序列第一个前缀和为-1的位置反转后,形成的序列不同。

反向:每个含n+1个"+"的序列,第一个前缀和为1的位置反转后,形成的不合法序列不同。

所以得到卡特兰数:Cn=C(2n,n)-C(2n,n-1)=C(2n,n)/(n+1)

例一、含n+1个节点的满二叉树形态数:中序遍历,向左+1向右-1,转化为入栈出栈序。

例二、圆上n个点连弦数:顺时针顺序每次+1和-1连弦,转化为入栈出栈序。

例三、n对括号表达式:左括号+1右括号-1,括号表达式组合数转化为入栈出栈序。

例四、n+1个数字连乘:结合n次即有n对有效括号,转化为括号表达式。

例五、凸n+2边形的三角剖分数:对边进行编号,然后顺时针扫描,实际上是n+1条边的连乘方案,转化为入栈出栈序。

二、不跨线路径数(几何模型)

入栈出栈序:考虑n*n的方格,从左下到右上不跨越对角线的路径数,向右记为+1,向上记为-1,跨越对角线就是前缀和为-1,则转化为入栈出栈序。

考虑n*m的方格,一条不合法路径在第一次跨越对角线的时候,将前面的路径翻转(上变左,左变上),那么就变成了到(n-1,m+1)的路径数。

那么f(n,m)=C(n+m,n)-C(n+m,n-1)。

 

【分治思想】

一个问题A,规模为n,可以用分治的思想,先固定一个元素,然后将剩下n-1个元素拆分成两个问题,根据固定的元素位置不同,两个问题分别是(0,n-1)(1,n-2)...(n-1,0)。

例一、入栈出栈序:固定最后出栈的数字是第k个加入的数,那么k前面是k-1个数的入栈出栈序问题,k后面是n-k个数的入栈出栈序问题,则有:

C(n)=C(0)*C(n-1)+C(1)*C(n-2)+...+C(n-1)C(0),即C(n)=ΣC(i)*C(n-i-1),i=0~n-1,C(0)=1

例二、凸n+2边形三角剖分数:先固定三角形V1VkVn+2,划分成凸k多边形和凸n+2-k边形,转化为Cn。

★总结:Catalan数的题目,一般从几种方式看出:转化为入栈出栈序,转化为几何不跨线路径数,定点分治思想,打表

以上是关于JAVA 方法的入栈出栈问题的主要内容,如果未能解决你的问题,请参考以下文章

关于汇编语言问题,入栈出栈啥用

如何用函数实现入栈和出栈

链栈算法

入栈操作的合法性 重复元素

算法专题卡特兰数(计数数列)

数据结构 | 栈:1051