「java栈参数」java中栈的使用

博主:adminadmin 2023-03-20 20:35:12 285

今天给各位分享java栈参数的知识,其中也会对java中栈的使用进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

java实参和形参都存在栈中吗?

JAVA传递参数有两种方式:值传递和引用传递

值传递是传递数据:象基本数据类型都是值传递

引用传递:对象的引用和数组的引用。

形参是方法中的局部变量,是方法调用时的那个栈中.实参可能根本就不是一个变量,仅仅是一个常量值(如:3)时,这时实参是不占内存空间的.当实参是一个变量或含有变量的表达式时,占用内存空间,且是另外一个空间中.

java 基础堆栈

你就简单的来理解就可以了

堆栈就是两种存放数据的方式

不要new直接来定义的是栈

用new来定义的就是堆

首先来讲解栈

栈的优势是,存取速度比堆要快。但缺点是缺乏灵活性

而堆测试速度慢

但是灵活性好

比如八大基本数据类型

在你int

sum

=

0;的时候

就是sum是一个指向

int

类型的引用,指向0这个字面值

你在顶一个

int

i=0;他会去找有没有0

有的话就会指向它

所以栈具有共享数据的特性

而当你String

str

=

new

String("a");的时候

它就会在堆中建立一个对象

其实你就理解成两种方式的存放数据的方式就行

JAVA堆栈问题

其实这些基础的东西网上有不少,

你可以多去csdn,那里可以学到不少好东西

,我就直接给你粘贴过来了

java中堆栈(stack)和堆(heap)

一、堆栈(stack)和堆(heap)?

(1)内存分配的策略

按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.

 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求.

 栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。

 静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放.

(2)堆和栈的比较

上面的定义从编译原理的教材中总结而来,除静态存储分配之外,都显得很呆板和难以理解,下面撇开静态存储分配,集中比较堆和栈:

 从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的.而这种不同又主要是由于堆和栈的特点决定的:

 在编程中,例如C/C++中,所有的方法调用都是通过栈来进行的,所有的局部变量,形式参数都是从栈中分配内存空间的。实际上也不是什么分配,只是从栈顶向上用就行,就好像工厂中的传送带(conveyor

belt)一样,Stack

Pointer会自动指引你到放东西的位置,你所要做的只是把东西放下来就行.退出函数的时候,修改栈指针就可以把栈中的内容销毁.这样的模式速度最快,当然要用来运行程序了.需要注意的是,在分配的时候,比如为一个即将要调用的程序模块分配数据区时,应事先知道这个数据区的大小,也就说是虽然分配是在程序运行时进行的,但是分配的大小多少是确定的,不变的,而这个"大小多少"是在编译时确定的,不是在运行时.

 

堆是应用程序在运行的时候请求操作系统分配给自己内存,由于从操作系统管理的内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低.但是堆的优点在于,编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。事实上,面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定.在C++中,要求创建一个对象时,只需用new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存.当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的好,人的优点往往也是人的缺点,人的缺点往往也是人的优点(晕~).

(3)JVM中的堆和栈

JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的.

从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。

 

每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程共享.跟C/C++不同,Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。

Java栈和本地方法栈方法调用栈,这些都是什么?

JAVA内存里面有一般有四个分类,堆, 栈(堆栈), 静态域, 常量池

栈: 实际上是一个队列, 遵循 FILO的原则(后进先出), 里面储存的是函数的参数值,局部变量,对象的引用(对象本身不在这里)等,因此在每调用一个函数时,堆栈都会分配一部分空间给它,函数返回时,被释放

堆: 储存静态变量,全局变量 和 用new创建的东西,栈中的内存是动态内存,其中的内存在不使用时随时可以被回收

静态域:存放对象中static定义的成员

常量池:存放常量

根据以上解释回答你的问题:

JAVA栈存的是函数的参数值,局部变量,对象的引用

方法调用栈? 没有这说法吧, 方法的调用是存在栈中的

本地方法栈, 和JAVA中的栈一个作用, 只是这个栈是属于本地的,不属于JAVA虚拟机,但受JAVA虚拟机的控制,因为是JAVA虚拟机简单地动态链接并直接调用指定的本地方法。可以把这看作是虚拟机利用本地方法来动态扩展自己

局部变量和对象引用存在 栈 中, 方法调用的栈帧也是在 栈 中

以上是我自己查资料+自己的理解,有错望指出

用java实现数据结构“栈

Java栈的实现

public class MyStack { //定义一个堆栈类

int[] array; //用int数组来保存数据,根据需要可以换类型

int s_size; //定义堆栈的宽度

public MyStack(int i){ //定义一个带参数构造器

array=new int[i]; //动态定义数组的长度

s_size=0; //堆栈的默认宽度为0

}

public MyStack(){ //默认构造器

this(50); //默认构造器可容纳50个元素

}

public void push(int i){ //压栈

array[this.s_size]=i;

this.s_size++;

}

public int pop(){ //从堆栈中取元素,从栈顶开始取

if(this.s_size!=0){

int t=array[s_size-1]; //用中间变量保存栈顶的元素

array[s_size-1]=0; //取完元素该位置设为0

s_size--; //栈的大小减1

return t; //返回栈顶元素

}else{

System.out.println("This stack is empty"); //当栈为空时显示提示信息,返回0

return 0;

}

}

public boolean isEmpty(){ //判断栈是否为空

return this.s_size==0;

}

public int top(){ //从栈顶取值,功能和 pop() 方法一样

if(!this.isEmpty()){

int t=array[this.s_size-1];

array[this.s_size-1]=0;

this.s_size--;

return t;

}else{

System.out.println("This stack is empty!");

return 0;

}

}

public void printAll(){ //打印出堆栈中的所有元素的值,不是取出,元素依然在堆栈里

if(!this.isEmpty()){

for(int i=this.s_size - 1;i=0;i--){

System.out.println(array[i]);

}

}

}

//下面是测试代码

public static void main(String[] args){

MyStack stack=new MyStack();

stack.push(4);

stack.push(5);

stack.push(6);

stack.push(7);

//System.out.println(stack.isEmpty());

stack.printAll();

System.out.println("===========");

System.out.println(stack.top());

System.out.println(stack.top());

System.out.println(stack.top());

System.out.println(stack.top());

System.out.println(stack.top());

}

}

java中堆和堆栈有什么区别

java中堆(heap)和堆栈(stack)有什么区别 stack 和 heep 都是内存的一部分

stack 空间小,速度比较快, 用来放对象的引用

heep 大,一般所有创建的对象都放在这里。

栈(stack):是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量.

在java中,所有基本类型和引用类型都在栈中存储.栈中数据的生存空间一般在当前scopes内(就是由{...}括起来的区域).

堆(heap):是一个可动态申请的内存空间(其记录空闲内存空间的链表由操作系统维护),C中的malloc语句所产生的内存空间就在堆中.

在java中,所有使用new xxx()构造出来的对象都在堆中存储,当垃圾回收器检测到某对象未被引用,则自动销毁该对象.所以,理论上说java中对象的生存空间是没有限制的,只要有引用类型指向它,则它就可以在任意地方被使用.

1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

3. Java中的数据类型有两种。

一种是基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char(注意,并没有string的基本类型)。 这种类型的定义是通过诸如int a = 3; long b = 255L;的形式来定义的,称为自动变量。值得注意的是,自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如int a = 3; 这里的a是一个指向int类型的引用,指向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与b的值后,再令a=4;那么,b不会等于4,还是等于3。在编译器内部,遇到a=4;时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。

4.String是一个特殊的包装类数据。即可以用String str = new String("abc");的形式来创建,也可以用String str = "abc";的形式来创建(作为对比,在JDK 5.0之前,你从未见过Integer i = 3;的表达式,因为类与字面值是不能通用的,除了String。而在JDK 5.0中,这种表达式是可以的!因为编译器在后台进行Integer i = new Integer(3)的转换!)。

前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。Java中的有些类,如DateFormat类,可以通过该类的getInstance()方法来返回一个新创建的类,似乎违反了此原则。其实不然。该类运用了单例模式来返回类的实例,只不过这个实例是在该类内部通过new()来创建的,而getInstance()向外部隐藏了此细节。那为什么在String str = "abc";中,并没有通过new()来创建实例,是不是违反了上述原则?其实没有。

关于java栈参数和java中栈的使用的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。