最后更新于2021年1月28日11:16:55
以前没有深究过 new 对象的语句,今天查询单例模式的实现,看到一篇文章觉得对自己理解对象引用有帮助,就转载了。
JAVA快速教程这一套都写得挺好的,很细,支持!
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

目录

  • 对象引用
  • 引用的赋值
  • 垃圾回收
  • 参数传递
  • 总结

对象引用

我们沿用之前定义的Human类,并有一个Test类:

public class Test
{public static void main(String[] args){Human aPerson = new Human(160);                 }
}class Human
{   /*** constructor*/public Human(int h){this.height = h;}/*** accessor*/public int getHeight(){return this.height;}/*** mutator*/public void growHeight(int h){this.height = this.height + h;}    private int height;
}

外部可以调用类来创建对象,比如上面在Test类中:

Human aPerson = new Human(160);

创建了一个Human类的对象aPerson。

上面是一个非常简单的表述,但我们有许多细节需要深入:

首先看等号的右侧。new是在内存中为对象开辟空间。具体来说,new是在内存的堆(heap)上为对象开辟空间。这一空间中,保存有对象的数据和方法。
再看等号的左侧。aPerson指代一个Human对象,被称为对象引用(reference)。实际上,aPerson并不是对象本身,而是类似于一个指向对象的指针。aPerson存在于内存的**栈(stack)**中。
当我们用等号赋值时,是将右侧new在堆中创建对象的地址赋予给对象引用。
这里的内存,指的是JVM (Java Virtual Machine)虚拟出来的Java进程内存空间。内存的堆和栈概念可参考Linux从程序到进程。

栈的读取速度比堆快,但栈上存储的数据受到有效范围的限制。在C语言中,当一次函数调用结束时,相应的栈帧(stack frame)要删除,栈帧上存储的参量和自动变量就消失了。Java的栈也受到同样的限制,当一次方法调用结束,该方法存储在栈上的数据将清空。在 Java中,所有的(普通)对象都储存在堆上。因此,new关键字的完整含义是,在堆上创建对象

**基本类型(primitive type)**的对象,比如int, double,保存在栈上。当我们声明基本类型时,不需要new。一旦声明,Java将在栈上直接存储基本类型的数据。所以,基本类型的变量名表示的是数据本身,不是引用。
引用和对象的关系就像风筝和人。我们看天空时(程序里写的),看到的是风筝(引用),但风筝下面对应的,是人(对象):
尽管引用和对象是分离的,但我们所有通往对象的访问必须经过引用这个“大门”,比如以 引用.方法() 的方式访问对象的方法。在Java中,我们不能跳过引用去直接接触对象。再比如,对象a的数据成员如果是一个普通对象b,a的数据成员保存的是指向对象b的引用 (如果是基本类型变量,那么a的数据成员保存的是基本类型变量本身了)。

在Java中,引用起到了指针的作用,但我们不能直接修改指针的值,比如像C语言那样将指针值加1。我们只能通过引用执行对对象的操作。这样的设计避免了许多指针可能引起的错误。

引用的赋值

当我们将一个引用赋值给另一个引用时,我们实际上复制的是对象的地址。两个引用将指向同一对象。比如 dummyPerson=aPerson;,将导致:

一个对象可以有多个引用 (一个人可以放多个风筝)。当程序通过某个引用修改对象时,通过其他引用也可以看到该修改。我们可以用以下Test类来测试实际效果:

public class Test
{public static void main(String[] args){Human aPerson = new Human(160);Human dummyPerson = aPerson;System.out.println(dummyPerson.getHeight());aPerson.growHeight(20);System.out.println(dummyPerson.getHeight());}
}

我们对aPerson的修改将影响到dummyPerson。这两个引用实际上指向同一对象。

所以,将一个引用赋值给另一个引用,并不能复制对象本身。我们必须寻求其他的机制来复制对象。

垃圾回收

随着方法调用的结束,引用基本类型变量会被清空。由于对象存活于堆,所以对象所占据的内存不会随着方法调用的结束而清空。进程空间可能很快被不断创建的对象占满。Java内建有**垃圾回收(garbage collection)**机制,用于清空不再使用的对象,以回收内存空间。

垃圾回收的基本原则是,当存在引用指向某个对象时,那么该对象不会被回收; 当没有任何引用指向某个对象时,该对象被清空。它所占据的空间被回收。

上图假设了某个时刻JVM中的内存状态。Human Object有三个引用: 来自栈的aPerson和dummyPerson,以及另一个对象的数据成员president。而Club Object没有引用。如果这个时候垃圾回收启动,那么Club Object将被清空,而Human Object来自Club Object的引用(president)也随之被删除。

垃圾回收是Java中重要的机制,它直接影响了Java的运行效率。我将在以后深入其细节。

参数传递

当我们分离了引用和对象的概念后,Java方法的参数传递机制实际上非常清晰: Java的参数传递为值传递。也就是说,当我们传递一个参数时,方法将获得该参数的一个拷贝。

实际上,我们传递的参数,一个是基本类型的变量,另一个为对象的引用。

基本类型变量的值传递,意味着变量本身被复制,并传递给Java方法。Java方法对变量的修改不会影响到原变量

引用的值传递,意味着对象的地址被复制,并传递给Java方法。Java方法根据该引用的访问将会影响对象

在这里有另一个值得一提的情况: 我们在方法内部使用new创建对象,并将该对象的引用返回。如果该返回被一个引用接收,由于对象的引用不为0,对象依然存在,不会被垃圾回收。

总结

new

引用,对象

被垃圾回收的条件

参数: 值传递

杂文(1):Java对象引用详解相关推荐

  1. Java虚拟机详解----JVM常见问题总结

    [正文] 声明:本文只是做一个总结,有关jvm的详细知识可以参考本人之前的系列文章,尤其是那篇:Java虚拟机详解04----GC算法和种类.那篇文章和本文是面试时的重点. 面试必问关键词:JVM垃圾 ...

  2. Java集合排序及java集合类详解

    Java集合排序及java集合类详解 (Collection, List, Set, Map) 摘要内容 集合是Java里面最常用的,也是最重要的一部分.能够用好集合和理解好集合对于做Java程序的开 ...

  3. 【Java】Java方法详解篇

    [Java]java方法详解篇 文章目录 [Java]java方法详解篇 方法 void修饰的方法的调用 方法的重载 方法的形参是基本数据类型 方法的形参是引用类型 递归结构 方法 方法:完成特定功能 ...

  4. Java synchronized详解

    Java synchronized详解 第一篇: 使用synchronized 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语--s ...

  5. Apache Thrift - java开发详解

    2019独角兽企业重金招聘Python工程师标准>>> Apache Thrift - java开发详解 博客分类: java 架构 中间件 1.添加依赖 jar <depen ...

  6. Java泛型详解-史上讲解最详细的,没有之一

    目录 1. 概述 2. 一个栗子 3. 特性 4. 泛型的使用 4.1 泛型类 4.2 泛型接口 4.3 泛型通配符 4.4 泛型方法 4.4.1 泛型方法的基本用法 4.4.2 类中的泛型方法 4. ...

  7. java 泛型详解、Java中的泛型方法、 java泛型详解

    本文参考java 泛型详解.Java中的泛型方法. java泛型详解 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即& ...

  8. 最详细的java泛型详解

    来源:最详细的java泛型详解 对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. ja ...

  9. Java异常详解及如何处理

    来源:Java异常详解及如何处理 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言 ...

最新文章

  1. SQL语句优化技术分析
  2. 影像组学视频学习笔记(23)-主成分析PCA、降维和特征筛选的区别、Li‘s have a solution and plan.
  3. 【网址收藏】spark on k8s operator github地址
  4. Windows 10下安装Docker Desktop
  5. java 三个版本区别_关于java三个版本的区别
  6. ZooKeeper未授权访问漏洞记录(影响范围:全版本,端口:2181)
  7. php插入方法,有什么办法能把一条php语句插入到方法里呢?
  8. Object-C---gt;Swift之(二)可选类型
  9. python操作数据库之删除数据
  10. 利用cropper插件进行图片裁剪
  11. 什么是和谐操作系统? 华为新操作系统介绍
  12. yara规则--构建yara规则库
  13. x86架构学习笔记实模式
  14. 一款真正可用的支付系统,可搭建自己的易支付系统,开源无后门可运营
  15. HTML 标签简写及全称以及HTML总结
  16. 计算机组成原理研究生试题三,计算机组成原理研究生入学试题.doc
  17. 《程序员》1月精彩内容:区块链技术与应用探索
  18. 如何隐藏微信内置底部前进后退的按钮?
  19. Python小工具——格雷码转换器
  20. 【微信电子书制作软件】名编辑电子杂志大师教程 | 添加图形

热门文章

  1. mysql架设手游_战神引擎手游架设教程
  2. win10上运行emwin
  3. 推荐给你的一个读书清单
  4. 使用CAD看图如何打印图纸的部分内容?
  5. 编程计算1 * 2 * 3+3 * 4 * 5+5 * 6 * 7+...+99 * 100 * 101的值。
  6. C语言入门题库——编写求圆面积和球体积的函数
  7. 【转载·SCTP协议】浅析 - SCTP协议
  8. LabVIEW模拟卡拉OK唱机的灯光显示效果
  9. 安装教程之PyCharm安装
  10. python云计算主要是干嘛的_阿里巴巴python云计算是干什么的