博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java学习笔记之深入理解引用
阅读量:6250 次
发布时间:2019-06-22

本文共 1485 字,大约阅读时间需要 4 分钟。

引言Java中数据传递的方式,除了基本数据类型是按照值传递,其它类型全部是按照引用传递,这和C++有很大区别,但是很多网上文章都解释的不清楚,甚至是错误的,在查阅资料之后,下面整理出一个比较容易理解的版本。

我们知道引用根据引用的类型不同有许多名称,如字符串引用,数组引用等等。

一、栈内存和堆内存

我们用数组来引出和解释这两个概念。

数组引用变量只是一个引用,这个引用可以指向任何有效的内存。

简单的理解就是,这个引用是用来存放数据地址的(数据地址指向数据在内存中的存储位置),在声明引用变量的时候,只是预留了一段空间来存储地址,但是还没有真正赋给这个引用变量一个地址,你赋给它哪个数据的地址,这个引用就指向这个地址(所以上面说“这个引用可以指向任何有效的内存”),那么你就可以通过这个引用访问该数据了。

如String[] p = new String(5);

p就是一个数组引用变量,这个数组含有5个元素。但是,实际数组元素被存储在堆(heap)中,而数组引用变量是被存在栈(stack)内存中,如下图:

也就是说,数组在内存中的存储实际是分别存储在两种不同性质的内存中:栈内存和堆内存。实际上,在Java中其它引用变量也是如此。

二、类的引用

考虑下面的自己建立的一个简单类:

class Test{   private int a;   Test()   {       a = 0;    }   public void set(int b)   {       a = b;    }        public void showInfo()   {       System.out.println("The value of a is :" + a);   }}

 

假如我们有如下语句:

Test m = new Test()

我们常常看到有这样的说法:m是一个对Test类的引用变量,感觉好难理解,怎么实例化一个类就成了引用呢?让我们一步一步来看这个实例化过程。

我们把上面语句拆开成下面语句:

Test m;

m = new Test();

我们知道,Java中除了内置基本类型,其他类型全部是引用,Test当然不是内置基本类型,所以Test m 就是建立了一个指向Test类的引用:

Test m是声明了一个Test类的引用变量m,就是告诉编译器要预留一部分栈内存给m,我会用m来存储一个地址指向存储有Test类对象存储单元,注意这个Test类对象和上面讲的数组元素一样,是存储在堆内存中的。但Test m也只是声明而已,但是指向哪一个Test类对象,目前还不知道,因为我们还没有赋给它一个Test 类对象的地址,它怎么可能知道指向哪儿?

m = new Test() 就是来给m指明方向的,new Test()构造了一个Test类对象,系统会给这个对象分配一定的内存空间留给这个对象存储自己的数据,通过运算m = new Test(),把这个新建的Test类对象在内存(堆内存)中的地址赋给m,于是m就知道它应该指向哪儿了:

总结出以下几点:

  • Java除了内置基本数据类型(int , double ,float等等)是值传递,其他类型的都是引用
  • 声明一个类型的引用时,只是为引用变量预留了一个存储地址空间,该引用变量可以指向任何有效的内存单元
  • Java大量使用引用的方式可以减少值传递过程中复制数据的开销,提高效率。

 

转载于:https://www.cnblogs.com/90zeng/p/Java_deep_reference.html

你可能感兴趣的文章
《机器学习实战》2.2.2分析数据:使用matplotlib创建散点图
查看>>
Linux如何查看当前占用CPU或内存最多的几个进程
查看>>
bit,byte,char,位,字节,字符 的区别
查看>>
Docker 容器入门
查看>>
[LeetCode] Pyramid Transition Matrix 金字塔转变矩阵
查看>>
几种查看CentOS系统版本号和位数的方法
查看>>
数字签名到底是什么鬼?
查看>>
GoldenGate实时投递数据到大数据平台(7)– Apache Hbase
查看>>
python安装h5py
查看>>
异常处理器
查看>>
生命的活力-负熵-秩序-结构
查看>>
[LeetCode] Number of Distinct Islands II 不同岛屿的个数之二
查看>>
Java NIO Overview
查看>>
MD5 和的价值体现在哪里,它是用来做什么的?
查看>>
NHibernate:no persister for 异常
查看>>
Spring Boot + Druid 监控数据库(三)
查看>>
C# MemoryCache GCHandle
查看>>
IDEA使用及优化
查看>>
复制文件到U盘错误0x80071AC3,请运行chkdsk并重试
查看>>
MySQL_插入更新 ON DUPLICATE KEY UPDATE
查看>>