基本数据类型不一定存储在栈中,是不是颠覆了你的认知

news/2025/3/26 2:20:15/

大家好,我是三叔,很高兴这期又和大家见面了,有很多小伙伴问我,基本数据类型一定在栈内存中吗?网上答案也是五花八门,部分读者都有被误导过,基本数据类型不一定在栈内存中!

虽然基本数据类型通常存储在栈内存中,但是也有一些情况下它们会存储在堆内存中。例如,当基本数据类型被封装为对应的包装类时,它们会被存储在堆内存中。当一个int类型的值被封装为Integer对象时,这个对象会被存储在堆内存中。

注意

基本数据类型不一定都在栈内存中:

  1. 如果是成员变量,基本数据类型变量名和对象 存放在堆中,引用类型也在堆中,是成员共享的。
  2. 如果在局部变量中,基本数据类型的变量名和值都在栈中,引用对象类型的变量名在栈中,值在堆中,当调用方法时,会在java栈中生成栈帧,局部变量就存放在方法栈中,当方法调用结束就会释放该栈帧,所以局部变量随栈帧的销毁而结束,这就是局部变量只能在方法中有效的原因。

eg:

// 成员变量class Demo{//a放在堆中,a中存放地址值,指向“abc”,“abc”放入堆中String a = "abc";//同理,b和1都放在堆中int b = 1;}class Demo{// 局部变量public void getName(){//变量名a:放在栈中,值:"abc"放在堆中String a = "abc";// 变量名b 和 值1都放在栈中int b = 1;}}

此外,当基本数据类型作为成员变量或数组元素被包含在一个对象中时,它们也会被存储在堆内存中。例如,如果一个类中有一个int类型的成员变量,那么每个该类的实例对象都会在堆内存中分配内存来存储这个成员变量。(下面我会举例说明)

不过,需要注意的是,尽管基本数据类型有可能被存储在堆内存中,但它们的值依然是不可变的。即使基本数据类型被存储在堆内存中,它们的值也不会被改变,因为Java中的基本数据类型都是不可变的。

补充

基本数据类型的存储方式

Java中的基本数据类型存储大部分情况在栈内存中。栈内存是一种临时存储区域,存储在栈内存中的数据的生命周期和所在的方法的生命周期是一样的。在Java中,每当定义一个基本数据类型的变量时,都会在栈内存中分配一段空间,用于存储变量的值。当这个变量超出其作用域时,这段空间就会被释放,这也就是Java的垃圾回收机制。

Java将基本数据类型存储在栈内存中,是为了提高程序的执行效率。因为基本数据类型的数据量很小,通常只需要占用几个字节的内存,将它们存储在栈内存中可以使它们的访问速度更快,而且不需要进行垃圾回收。

值类型与引用类型

基本数据类型在Java中被定义为值类型,也就是说,它们的变量和数据是直接存储在栈内存中的,而不是存储在堆内存中的。与引用类型相比,值类型的存储方式更加高效,因为它们不需要进行指针的解引用和内存的分配和回收。

基本数据类型在堆内存

基本数据类型通常存储在栈内存中,但是也有一些情况下它们会存储在堆内存中。例如,当基本数据类型被封装为对应的包装类时,它们会被存储在堆内存中。当一个int类型的值被封装为Integer对象时,这个对象会被存储在堆内存中。

此外,当基本数据类型作为成员变量或数组元素被包含在一个对象中时,它们也会被存储在堆内存中。例如,如果一个类中有一个int类型的成员变量,那么每个该类的实例对象都会在堆内存中分配内存来存储这个成员变量。

@Data
public class Student {private int id;private String name;private int[] scores;public Student(int id, String name, int[] scores) {this.id = id;this.name = name;this.scores = scores;}public Student(int[] scores) {this.scores = scores;}public void printInfo() {System.out.println("Student ID: " + id);System.out.println("Student Name: " + name);System.out.print("Scores: ");for (int i = 0; i < scores.length; i++) {System.out.print(scores[i] + " ");}System.out.println();}
}public class Demo{public static void main(String[] args) {int[] scores = {90, 85, 95};Student student = new Student(1, "Tom", scores);student.printInfo();}
}

在这里插入图片描述

在这个例子中,定义了一个Student类,其中有一个int类型的成员变量id,一个String类型的成员变量name和一个int类型的数组成员变量scores。在main方法中,创建了一个int类型的数组scores,并将它作为参数传递给了Student类的构造方法,这个数组将会被存储在堆内存中。

直接修改了 scores 数组的第一个元素的值,并打印了通过 student 对象获取到的 scores 数组,发现 scores 数组的值已经被改变了。

public class Demo {public static void main(String[] args) {int[] scores = {90, 85, 95};Student student = new Student(scores);scores[0] = 95;System.out.println(Arrays.toString(student.getScores()));}
}

在这里插入图片描述

scores 数组在存储在堆内存中的 Student 对象中时,是以引用类型的方式存储的,而引用类型变量存储的是对象在堆中的内存地址,所以改变 scores 数组的值会直接影响到存储在堆内存中的 Student 对象的 scores 成员变量。

基本数据类型和引用类型的区别

基本数据类型是Java基础数据类型(byte、short、int、long、float、double、char和boolean),而引用类型则是Java中的类、接口和数组类型(例如上面的int[] 数组)。基本数据类型和引用类型的区别主要体现在它们在内存中的存储方式和赋值方式上。

基本数据类型的值存储在栈内存中,而引用类型的值(也就是对象)存储在堆内存中。基本数据类型的变量存储着它们的值本身,而引用类型的变量存储着指向对象的引用。

在Java中,基本数据类型是被定义为值类型,也就是说,它们的变量和数据是直接存储在栈内存中的,而不是存储在堆内存中的。与引用类型相比,值类型的存储方式更加高效,因为它们不需要进行指针的解引用和内存的分配和回收。

另外,基本数据类型和引用类型的赋值方式也是有区别的。当我们给一个基本数据类型的变量赋值时,实际上是将一个值复制到了这个变量所在的内存空间中。而当我们给一个引用类型的变量赋值时,实际上是将一个指向对象的引用复制到了这个变量所在的内存空间中。因此,如果两个引用变量指向同一个对象,那么改变其中一个引用变量所指向的对象的状态,将会影响到另一个。


http://www.ppmy.cn/news/69115.html

相关文章

Linux入门篇-安装CentOS

一、先组织硬件 先把“买”一台空白的电脑&#xff0c;再进行操作系统的安装。 windows中&#xff0c;处理器&#xff1a; 本机 实际运行的时候能当多少个CPU来使呢&#xff1f;16个 处理器的数量是CPU的数量&#xff1b;&#xff08;本机上一个插槽&#xff0c;就只有一个CP…

3年测试技术面一题都看不懂,字节面试真的变态.....

最近我的一个读者朋友去了字节面试&#xff0c;来给我发信息吐槽&#xff0c;说字节的面试太困难了&#xff0c;像他这种三年经验的测试员&#xff0c;在技术面&#xff0c;居然一题都答不上来&#xff0c;这要多高的水平才能有资格去面试字节的测试岗位。 确实&#xff0c;字…

ASEMI代理ADI亚德诺ADUM3211TRZ-RL7原厂芯片

编辑-Z ADUM3211TRZ-RL7参数描述&#xff1a; 型号&#xff1a;ADUM3211TRZ-RL7 数据速率&#xff1a;10 Mbps 传播延迟&#xff1a;50 ns 脉冲宽度失真&#xff1a;3 ns 脉冲宽度&#xff1a;100 ns 输出上升/下降时间&#xff1a;2.5 ns 供电电流&#xff1a;2.6 mA …

Qt——Qt控件之输入窗口-QDial数字拨盘框控件的使用总结(例程:旋转码盘改变数值显示 )

【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》

Python requests 模块

Python中的requests模块是一个HTTP客户端库&#xff0c;它允许您向任何Web服务器发送HTTP请求并获取响应。 下面是一个简单的示例&#xff0c;向某个网站发送一个HTTP GET请求&#xff1a; python import requests response requests.get("http://www.example.com&quo…

人机融合智能与哲学

GPT系列的大型语言模型&#xff08;LLM&#xff09;在初步成功之后&#xff0c;需要人们重新审视图灵的计算理论&#xff0c;重新认识计算的本质和形式&#xff0c;重新思考计算机和计算机理论&#xff0c;以及深入思考计算的家族、广义的计算和计算的哲学等问题。这是因为GPT系…

ChatGPT1论文解读《Improving Language Understanding by Generative Pre-Training》

论文总结 以下是我阅读完整篇论文做的个人总结&#xff0c;基本包含了chatGPT1设计的完整框架思路&#xff0c;可以仅看【论文总结】章节。 在GPT1实现的核心架构中&#xff0c;包含两个阶段。 第一阶段 在第一阶段基于一个包含7000本书籍内容的海量未标注文本数据集进行无…

1. ZKP 研究框架及相关内容概述

ZK简介 最初在1980年提出,由Shafi Goldwasser, Silvio Micali和Charles Rackoff。刚开始叫做交互式证明系统 (Interactive proof system)。 Prover 和 Verifier 之间交换信息,让 Verifier 相信某种 statement 是真的。而不透露给 Verifier 过多与证明无关的信息。 ZK 是解…