【JAVA】堆、栈的理解

引言
在Java中,内存管理是一个重要的概念,它涉及到堆(Heap)和栈(Stack)两种主要的内存区域。理解这两者对于编写高效、稳定的Java代码至关重要。

堆和栈的简单描述

函数中定义的基本类型变量,对象的引用变量都在函数的栈内存中分配。
栈内存中存储的是对象的引用地址,栈内存中的数据,没有默认初始化值,需要手动设置。栈内存特点,数据一执行完毕,变量会立即释放,节约内存空间。

堆内存用来存放new创建的对象和数组。
堆内存中所有的实体都有内存地址值。
堆内存中的实体不再被指向时,JVM启动垃圾回收机制,自动清除,这也是JAVA优于C++的表现之一(C++中需要程序员手动清除)。

示例1

public static void main(String[] args) {
        List<ModelUploadParam> list = new ArrayList<>();
        test(list);
        System.out.println(list);
    }
static void test(List<ModelUploadParam> list){
        list = null;
        System.out.println(list);
    }

第一步:执行main函数,定义list集合,在栈内存中开辟一个空间存放list变量,同时,在堆内存中也开辟一个空间存放ArrayList对象,堆内存会自动分配地址值,如0x0045。
第二部:执行test函数,传递list的引用拷贝,方法参数传递机制是按值传递(pass-by-value)
第三步:对test函数中list赋null,修改的是方法内部引用的副本,只改变了引用变量的指向,并没有改变原始引用或堆中的对象。原始引用仍然指向最初的对象,因此原始对象不会受到影响。
在这里插入图片描述

示例2

public static void main(String[] args) {
        List<ModelUploadParam> list = new ArrayList<>();
        test(list);
        System.out.println(list);
    }
static void test(List<ModelUploadParam> list){
        list.clear();
        System.out.println(list);
    }

与实例1不同的是,list.clear()修改的是堆中的对象内容,因为调用的是对象的方法。无论是原始引用还是方法内部的引用,指向的都是同一个堆中的对象,因此修改后会影响原始对象。

如何判断操作的是原始对象本身还是引用地址的变量(个人理解,仅作为记录)

  • list. 调用的是引用所指向的原始对象的方法或属性。这意味着对对象本身的操作,比如 list.clear() 或 list.add(),会影响到引用所指向的那个对象,因为它们操作的是堆中的对象内容。
  • list = 修改的是引用地址。这意味着你在改变引用变量本身,让它指向另一个对象或者 null,但不会影响到原始对象或其他引用指向该对象。
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Accccccccv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值