java堆栈内存,值传递详解

值传递也能传地址哦

首先要记住:java中都是值传递 为什么,详见——

https://blog.csdn.net/bjweimengshu/article/details/79799485

但是不是说就不传递地址了

我们知道,编程语言中需要进行方法间的参数传递,这个传递的策略叫做求值策略。在程序设计中,求值策略有很多种,比较常见的就是值传递和引用传递。还有一种值传递的特例——共享对象传递。值传递和引用传递最大的区别是传递的过程中有没有复制出一个副本来,如果是传递副本,那就是值传递,否则就是引用传递。在Java中,其实是通过值传递实现的参数传递,只不过对于Java对象的传递,传递的内容是****对象的引用。我们说Java中只有值传递,只不过传递的内容是对象的引用。这也是没毛病的。但是,绝对不能认为Java中有引用传递。

  • 传递的参数如果是普通类型,是值传递,传递的是值
  • 如果是对象或引用类型,也是值传递,只不过传递的是地址
  • 值传递:传递的是堆中地址
  • 引用传递:传递的是栈中地址

图形详解

class Point{
    double x;
    double y;
    Point(double x,double y){
        this.x=x;
        this.y=y;
    }
}

class Line{
    Point start;
    Point end;
    Line(Point u,Point v){
        this.start=u;
        this.end=v;
    }
    public double getLineLength(){
        return Math.sqrt((start.x-end.x)*(start.x-end.x)+(start.y=end.y)*(start.y-end.y));
    }
}

public class Test{
    public static void main(String[] args){
        Point a=new Point(3,4);
        Point b=new Point(0,0);
        Line L=new Line(a,b);
        System.out.println(L.getLineLength());
    }
}

在这里插入图片描述

  1. Test类肯定放进方法区,同时必须放进去的还有Test的构造方法
  2. 主方法是静态方法,放在静态方法区
  3. 在函数中定义的一些基本类型的变量。和对象的引用变量都在函数的栈内存中分配
  4. new的新对象先初始化,默认值为0,初始化后,构造方法进栈(注意:构造方法是写在Person里的)
  5. 首先要有个this所属,知道谁调用的它
  6. 等覆盖完,拿到值后,再把地址值0x0034赋值给a
  7. 再然后,构造方法就可以弹栈了,然后b的操作和a是一样的

24行时, Point就进了方法区,26行时Line进方法区,因为两个类里边都没有静态方法,所以静态方法区不添加东西

在这里插入图片描述

  1. L(对象的引用变量入栈)
  2. new Line在堆中创建新空间,Line类中新定义的两个变量,进入此空间,初始值默认为null
  3. Line的构造方法进栈this指向此新空间的地址,u,v两个方法的参数,分别指向a,b
  4. 将这个值传到堆里,让start和end获得这俩值
  5. 最后将新空间的地址赋值给L

在这俩图上补充的内容

start等于的是地址,假如存在start.arr[0]=“999”,点儿出来的要在堆中开辟新空间来存储“999”

Java中对象、对象引用、堆、栈、值传递以及引用传递的详解

1.对象和对象引用的差别:

(1).对象:

万物皆对象。对象是类的实例。

在Java中new是用来在堆上创建对象用的。

一个对象能够被多个引用所指向。

(2).对象引用:

相似于C++中的地址。通过对象引用能够找到对象

一个引用能够指向多个对象。操纵的标识符实际上是指向对象的引用。

就像:对象存放在屋子里,对象的引用就相当于屋子的钥匙。

2.值传递和引用传递的差别:

  • 值传递传的是堆中的地址
  • 引用传递传的是栈中地址

(1).值传递:传递的是值的拷贝。

也就是说传递后就互不相关了。

(2).引用传递:传递的是值的引用。是内存空间的地址。

也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

3.堆和栈的差别:

(1).栈:在函数中定义的一些基本类型的变量。和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间。当超过变量的作用域后。Java会自己主动释放掉为该变量所分配的内存空间。该内存空间能够马上被另作他用。

引用变量就相当于是为数组或对象起的一个名称。以后就能够在程序中使用栈中的引用变量来訪问堆中的数组或对象。

(2).堆:堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自己主动垃圾回收器来管理。

(3).生命周期:

A.引用变量的生命周期:程序执行一直到变量的作用域之外就被释放

B.数组和对象的生命周期:程序执行到使用new产生数组或者对象的语句所在的代码块之外,数组和对象本身占领的内存不会被释放。数组和对象在没有引用变量指向它的时候,才变为垃圾,不能再被使用。但仍然占领内存空间不放,在随后的一个不确定的时间被垃圾回收器收走。

这也是Java比較占内存的原因,实际上栈中的变量指向堆内存中的变量,这就是Java中的指针。

4.Java中的内存机制:

Java把内存分为两种:一种是栈内存。一种是堆内存。

栈内存:在函数中定义的一些基本类型的变量和对象的引用变量。

堆内存:由new创建的对象和数组。在堆中产生了一个数组或者对象之后,还能够在栈中定义一个特殊的变量。让栈中的这个变量的取值等于数组或对象在堆内存中的****首地址。

栈中的这个变量就成了数组或对象的引用变量。以后就能够在程序中使用栈中的引用变量来訪问堆中的数组或者对象,引用变量就相当于是为数组或对象起的一个名称。引用变量是普通的变量,定义时在栈中分配。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值